diff options
Diffstat (limited to 'docs')
379 files changed, 0 insertions, 44485 deletions
diff --git a/docs/ACE-FMM.html b/docs/ACE-FMM.html deleted file mode 100644 index 1cf4c06b869..00000000000 --- a/docs/ACE-FMM.html +++ /dev/null @@ -1,238 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>ACE FMM</title> - </head> - - <body bgcolor=#ffffff> -<center> -<font face=helvetica size=5>ACE Frequently Made Mistakes</font> - -<br> -<br> -<table border=0 cellpadding=3 cellspacing=1 width=550> - -<tr> -<td align=right valign=top> - <b>symptom</b> -</td> -<td align=left valign=top> - ACE_Task::getq() returns the error - <b>resource temporarily unavailable</b> -</td> -</tr> -<tr> -<td align=right valign=top> - <b>probable cause</b> -</td> -<td align=left valign=top> - Your Task is a subclass of ACE_Task<ACE_NULL_SYNCH> and - you are using it in a multithreaded program. -</td> -</tr> -<tr> -<td align=right valign=top> - <b>solution</b> -</td> -<td align=left valign=top> - Try using ACE_Task<ACE_MT_SYNCH> - instead so that the associated Message_Queue - is configured for access by multiple threads. -</td> -<tr><td colspan=2><hr noshade></td></tr> - -<tr> -<td align=right valign=top> - <b>symptom</b> -</td> -<td align=left valign=top> - ACE_Task::wait() throws an assert violation -</td> -</tr> -<tr> -<td align=right valign=top> - <b>probable cause</b> -</td> -<td align=left valign=top> - When you activate()d your Task, you specified - THR_DETACHED, which causes wait() to be unable to perform what you - want it to. -</td> -</tr> -<tr> -<td align=right valign=top> - <b>solution</b> -</td> -<td align=left valign=top> - Make sure you specify the flag THR_JOINABLE when activating - your ACE_Task object. -</td> -<tr><td colspan=2><hr noshade></td></tr> - - - -<tr> -<td align=right valign=top> - <b>symptom</b> -</td> -<td align=left valign=top> - Apparent race conditions when spawning threads (or activating Tasks) - from within a constructor. -</td> -</tr> -<tr> -<td align=right valign=top> - <b>probable cause</b> -</td> -<td align=left valign=top> - You are not guaranteed to have a valid <b>this</b> pointer - until the constructor has exited. Threads spawned from - a constructor are free to run - immediately, and may attempt to use an invalid <b>this</b> pointer. - -</td> -</tr> -<tr> -<td align=right valign=top> - <b>solution</b> -</td> -<td align=left valign=top> - Move your Task activations and other thread-spawning activites - <b>out</b> of the constructor. -</td> -<tr><td colspan=2><hr noshade></td></tr> - - - -<tr> -<td align=right valign=top> - <b>symptom</b> -</td> -<td align=left valign=top> - Compiler issues warnings/erros regarding using too few template - arguments, such as "'ACE_Svc_Handler' : too few template arguments". -</td> -</tr> -<tr> -<td align=right valign=top> - <b>probable cause</b> -</td> -<td align=left valign=top> - Instead of using the appropriate macro, you supplied an actual class - name as a parameter. This will fail depending upon platform and compiler, - due to the way templates are handled. -</td> -</tr> -<tr> -<td align=right valign=top> - <b>solution</b> -</td> -<td align=left valign=top> - Instead of instantiating a template class like <b>ACE_Svc_Handler<<u>ACE_SOCK_Stream</u>, ACE_NULL_SYNCH></b>, use the form of <b>ACE_Svc_Handler<<u>ACE_SOCK_STREAM</u>, ACE_NULL_SYNCH></b> which circumvents the platform peculiarities by using the macro. This also applies to some other template classes. -</td> -<tr><td colspan=2><hr noshade></td></tr> - - - -<tr> -<td align=right valign=top> - <b>symptom</b> -</td> -<td align=left valign=top> - Unable to compare ACE_thread_t variables (such as ACE_Thread::self()) using - operator==(). -</td> -</tr> -<tr> -<td align=right valign=top> - <b>probable cause</b> -</td> -<td align=left valign=top> - On some platforms, thread ids are numeric, and on some, they aren't. On some - implementations, simple a == b comparisons - are legal and sane. Some are not. - -</td> -</tr> -<tr> -<td align=right valign=top> - <b>solution</b> -</td> -<td align=left valign=top> - Use the <b>ACE_OS::thr_equal()</b> function to reliably compare thread - ids, regardless of platform. -</td> -<tr><td colspan=2><hr noshade></td></tr> - -<tr> -<td align=right valign=top> - <b>symptom</b> -</td> -<td align=left valign=top> - ACE_Reactor::run_event_loop() does not seem to function correctly - for a Reactor created in your application. -</td> -</tr> -<tr> -<td align=right valign=top> - <b>probable cause</b> -</td> -<td align=left valign=top> - You have not set the ACE_Reactor::instance() to refer to your new reactor. - run_event_loop only functions on the reactor currently installed as the - global Singleton. -</td> -</tr> -<tr> -<td align=right valign=top> - <b>solution</b> -</td> -<td align=left valign=top> - Use the <b>ACE_Reactor::instance(ACE_Reactor *, - int delete_reactor = 0)</b> static method to install your reactor as the global - Singleton before calling run_event_loop(). -</td> -<tr><td colspan=2><hr noshade></td></tr> - - - - -<!-- - -<tr> -<td align=right valign=top> - <b>symptom</b> -</td> -<td align=left valign=top> - -</td> -</tr> -<tr> -<td align=right valign=top> - <b>probable cause</b> -</td> -<td align=left valign=top> - -</td> -</tr> -<tr> -<td align=right valign=top> - <b>solution</b> -</td> -<td align=left valign=top> - -</td> -<tr><td colspan=2><hr noshade></td></tr> - ---> -<tr> -<td align=center colspan=2> -<font size=2>maintained by <a href="mailto:bob@werken.com">bob@werken.com</a></font> -</td> -</tr> - -</table> -</center> -</body> -</html> - diff --git a/docs/ACE-categories.html b/docs/ACE-categories.html deleted file mode 100644 index e8768a31f37..00000000000 --- a/docs/ACE-categories.html +++ /dev/null @@ -1,775 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> <head> -<title>ACE Class Categories</title> -</head> -<body> - -<BODY text = "#000000" -link="#000fff" -vlink="#ff0f0f" -bgcolor="#ffffff"> - -<HR><P> -<h3><a href = "http://www.cs.wustl.edu/~schmidt/ACE.html">ACE</a> Class Categories</h3> - -This document groups each file in <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ace">$ACE_ROOT/ace</A> -into its appropriate class category and provides a link to the C++ -source code and <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/man/acewindex.html">HTML -versions</A> of the relevant manual pages</A>. <P> - -<b>[ACE]</b> -<ul> -<b>[CORBA]</b> -<ul> -<li><a href = "../ace/CORBA_Handler.cpp">CORBA_Handler.cpp</a></li> -<li><a href = "../ace/CORBA_Handler.h">CORBA_Handler.h</a></li> -<b><a href = "../man/html/ACE_CORBA_Handler.html">[man page]</a></b> -<li><a href = "../ace/CORBA_Handler.i">CORBA_Handler.i</a></li> -<li><a href = "../ace/CORBA_Ref.cpp">CORBA_Ref.cpp</a></li> -<li><a href = "../ace/CORBA_Ref.h">CORBA_Ref.h</a></li> -<b><a href = "../man/html/ACE_CORBA_Ref.html">[man page]</a></b> -<li><a href = "../ace/CORBA_Ref.i">CORBA_Ref.i</a></li> -</ul> -<b>[Containers]</b> -<ul> -<li><a href = "../ace/Array.cpp">Array.cpp</a></li> -<li><a href = "../ace/Array.h">Array.h</a></li> -<b><a href = "../man/html/ACE_Array.html">[man page]</a></b> -<li><a href = "../ace/Array.i">Array.i</a></li> -<li><a href = "../ace/Containers.cpp">Containers.cpp</a></li> -<li><a href = "../ace/Containers.i">Containers.i</a></li> -<li><a href = "../ace/Containers.h">Containers.h</a></li> -<li><a href = "../ace/Hash_Map_Manager.cpp">Hash_Map_Manager.cpp</a></li> -<li><a href = "../ace/Hash_Map_Manager.h">Hash_Map_Manager.h</a></li> -<b><a href = "../man/html/ACE_Hash_Map_Manager.html">[man page]</a></b> -<li><a href = "../ace/Filecache.cpp">Filecache.cpp</a></li> -<li><a href = "../ace/Filecache.h">Filecache.h</a></li> -<b><a href = "../man/html/ACE_Filecache.html">[man page]</a></b> -<li><a href = "../ace/Free_List.cpp">Free_List.cpp</a></li> -<li><a href = "../ace/Free_List.i">Free_List.i</a></li> -<li><a href = "../ace/Free_List.h">Free_List.h</a></li> -<b><a href = "../man/html/ACE_Free_List.html">[man page]</a></b> -<li><a href = "../ace/Managed_Object.cpp">Managed_Object.cpp</a></li> -<li><a href = "../ace/Managed_Object.h">Managed_Object.h</a></li> -<b><a href = "../man/html/ACE_Managed_Object.html">[man page]</a></b> -<li><a href = "../ace/Managed_Object.i">Managed_Object.i</a></li> -<li><a href = "../ace/Map_Manager.cpp">Map_Manager.cpp</a></li> -<li><a href = "../ace/Map_Manager.h">Map_Manager.h</a></li> -<b><a href = "../man/html/ACE_Map_Manager.html">[man page]</a></b> -<li><a href = "../ace/Map_Manager.i">Map_Manager.i</a></li> -<li><a href = "../ace/Object_Manager.cpp">Object_Manager.cpp</a></li> -<li><a href = "../ace/Object_Manager.i">Object_Manager.i</a></li> -<li><a href = "../ace/Object_Manager.h">Object_Manager.h</a></li> -<b><a href = "../man/html/ACE_Object_Manager.html">[man page]</a></b> -<li><a href = "../ace/SString.cpp">SString.cpp</a></li> -<li><a href = "../ace/SString.h">SString.h</a></li> -<b><a href = "../man/html/ACE_SString.html">[man page]</a></b> -<li><a href = "../ace/SString.i">SString.i</a></li> -</ul> -<b>[Concurrency]</b> -<ul> -<li><a href = "../ace/Activation_Queue.h">Activation_Queue.h</a></li> -<b><a href = "../man/html/ACE_Activation_Queue.html">[man page]</a></b> -<li><a href = "../ace/Activation_Queue.cpp">Activation_Queue.cpp</a></li> -<li><a href = "../ace/Atomic_Op.i">Atomic_Op.i</a></li> -<li><a href = "../ace/Future.h">Future.h</a></li> -<b><a href = "../man/html/ACE_Future.html">[man page]</a></b> -<li><a href = "../ace/Future.cpp">Future.cpp</a></li> -<li><a href = "../ace/Method_Request.h">Method_Request.h</a></li> -<b><a href = "../man/html/ACE_Method_Request.html">[man page]</a></b> -<li><a href = "../ace/Method_Request.cpp">Method_Request.cpp</a></li> -<li><a href = "../ace/Process.cpp">Process.cpp</a></li> -<li><a href = "../ace/Process.h">Process.h</a></li> -<b><a href = "../man/html/ACE_Process.html">[man page]</a></b> -<li><a href = "../ace/Process.i">Process.i</a></li> -<li><a href = "../ace/Process_Manager.cpp">Process_Manager.cpp</a></li> -<li><a href = "../ace/Process_Manager.h">Process_Manager.h</a></li> -<b><a href = "../man/html/ACE_Process_Manager.html">[man page]</a></b> -<li><a href = "../ace/Process_Manager.i">Process_Manager.i</a></li> -<li><a href = "../ace/Sched_Params.cpp">Sched_Params.cpp</a></li> -<li><a href = "../ace/Sched_Params.h">Sched_Params.h</a></li> -<b><a href = "../man/html/ACE_Sched_Params.html">[man page]</a></b> -<li><a href = "../ace/Sched_Params.i">Sched_Params.i</a></li> -<li><a href = "../ace/Synch.cpp">Synch.cpp</a></li> -<li><a href = "../ace/Synch.h">Synch.h</a></li> -<b><a href = "../man/html/ACE_Synch.html">[man page]</a></b> -<li><a href = "../ace/Synch.i">Synch.i</a></li> -<li><a href = "../ace/Synch_Options.cpp">Synch_Options.cpp</a></li> -<li><a href = "../ace/Synch_Options.h">Synch_Options.h</a></li> -<b><a href = "../man/html/ACE_Synch_Options.html">[man page]</a></b> -<li><a href = "../ace/Synch_Options.i">Synch_Options.i</a></li> -<li><a href = "../ace/Synch_T.cpp">Synch_T.cpp</a></li> -<li><a href = "../ace/Synch_T.h">Synch_T.h</a></li> -<b><a href = "../man/html/ACE_Synch_T.html">[man page]</a></b> -<li><a href = "../ace/Synch_T.i">Synch_T.i</a></li> -<li><a href = "../ace/Thread.cpp">Thread.cpp</a></li> -<li><a href = "../ace/Thread.h">Thread.h</a></li> -<b><a href = "../man/html/ACE_Thread.html">[man page]</a></b> -<li><a href = "../ace/Thread.i">Thread.i</a></li> -<li><a href = "../ace/Thread_Manager.cpp">Thread_Manager.cpp</a></li> -<li><a href = "../ace/Thread_Manager.h">Thread_Manager.h</a></li> -<b><a href = "../man/html/ACE_Thread_Manager.html">[man page]</a></b> -<li><a href = "../ace/Thread_Manager.i">Thread_Manager.i</a></li> -<li><a href = "../ace/Token.cpp">Token.cpp</a></li> -<li><a href = "../ace/Token.h">Token.h</a></li> -<b><a href = "../man/html/ACE_Token.html">[man page]</a></b> -<li><a href = "../ace/Token.i">Token.i</a></li> -</ul> -<b>[Config]</b> -<ul> -<li><a href = "../ace/config.h">config.h</a></li> -<li><a href = "../ace/Basic_Types.cpp">Basic_Types.cpp</a></li> -<li><a href = "../ace/Basic_Types.h">Basic_Types.h</a></li> -<li><a href = "../ace/Basic_Types.i">Basic_Types.i</a></li> -<li><a href = "../ace/Version.h">Version.h</a></li> -</ul> -<b>[Connection]</b> -<ul> -<li><a href = "../ace/Acceptor.cpp">Acceptor.cpp</a></li> -<li><a href = "../ace/Acceptor.h">Acceptor.h</a></li> -<b><a href = "../man/html/ACE_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/Acceptor.i">Acceptor.i</a></li> -<li><a href = "../ace/Asynch_Acceptor.cpp">Asynch_Acceptor.cpp</a></li> -<li><a href = "../ace/Asynch_Acceptor.h">Asynch_Acceptor.h</a></li> -<b><a href = "../man/html/ACE_Asynch_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/Asynch_Acceptor.i">Asynch_Acceptor.i</a></li> -<li><a href = "../ace/Asynch_IO.cpp">Asynch_IO.cpp</a></li> -<li><a href = "../ace/Asynch_IO.h">Asynch_IO.h</a></li> -<li><a href = "../ace/Asynch_IO.i">Asynch_IO.i</a></li> -<li><a href = "../ace/Connector.cpp">Connector.cpp</a></li> -<li><a href = "../ace/Connector.h">Connector.h</a></li> -<b><a href = "../man/html/ACE_Connector.html">[man page]</a></b> -<li><a href = "../ace/Connector.i">Connector.i</a></li> -<li><a href = "../ace/Dynamic_Service.cpp">Dynamic_Service.cpp</a></li> -<li><a href = "../ace/Dynamic_Service.h">Dynamic_Service.h</a></li> -<b><a href = "../man/html/ACE_Dynamic_Service.html">[man page]</a></b> -<li><a href = "../ace/Dynamic_Service.i">Dynamic_Service.i</a></li> -<li><a href = "../ace/Strategies.cpp">Strategies.cpp</a></li> -<li><a href = "../ace/Strategies.h">Strategies.h</a></li> -<li><a href = "../ace/Strategies.i">Strategies.i</a></li> -<li><a href = "../ace/Strategies_T.cpp">Strategies_T.cpp</a></li> -<li><a href = "../ace/Strategies_T.h">Strategies_T.h</a></li> -<li><a href = "../ace/Strategies_T.i">Strategies_T.i</a></li> -<li><a href = "../ace/Svc_Handler.cpp">Svc_Handler.cpp</a></li> -<li><a href = "../ace/Svc_Handler.h">Svc_Handler.h</a></li> -<b><a href = "../man/html/ACE_Svc_Handler.html">[man page]</a></b> -<li><a href = "../ace/Svc_Handler.i">Svc_Handler.i</a></li> -</ul> -<b>[IPC]</b> -<ul> -<b>[IO_SAP]</b> -<ul> -<li><a href = "../ace/IO_SAP.cpp">IO_SAP.cpp</a></li> -<li><a href = "../ace/IO_SAP.h">IO_SAP.h</a></li> -<b><a href = "../man/html/ACE_IO_SAP.html">[man page]</a></b> -<li><a href = "../ace/IO_SAP.i">IO_SAP.i</a></li> -<br> -<b>[DEV_SAP]</b> -<ul> -<li><a href = "../ace/DEV.cpp">DEV.cpp</a></li> -<li><a href = "../ace/DEV.h">DEV.h</a></li> -<b><a href = "../man/html/ACE_DEV.html">[man page]</a></b> -<li><a href = "../ace/DEV.i">DEV.i</a></li> -<li><a href = "../ace/DEV_Connector.cpp">DEV_Connector.cpp</a></li> -<li><a href = "../ace/DEV_Connector.h">DEV_Connector.h</a></li> -<b><a href = "../man/html/ACE_DEV_Connector.html">[man page]</a></b> -<li><a href = "../ace/DEV_Connector.i">DEV_Connector.i</a></li> -<li><a href = "../ace/DEV_IO.cpp">DEV_IO.cpp</a></li> -<li><a href = "../ace/DEV_IO.h">DEV_IO.h</a></li> -<b><a href = "../man/html/ACE_DEV_IO.html">[man page]</a></b> -<li><a href = "../ace/DEV_IO.i">DEV_IO.i</a></li> -<li><a href = "../ace/TTY_IO.cpp">TTY_IO.cpp</a></li> -<li><a href = "../ace/TTY_IO.h">TTY_IO.h</a></li> -<b><a href = "../man/html/ACE_TTY_IO.html">[man page]</a></b> -</ul> -<b>[FILE_SAP]</b> -<ul> -<li><a href = "../ace/FILE.cpp">FILE.cpp</a></li> -<li><a href = "../ace/FILE.h">FILE.h</a></li> -<b><a href = "../man/html/ACE_FILE.html">[man page]</a></b> -<li><a href = "../ace/FILE.i">FILE.i</a></li> -<li><a href = "../ace/FILE_Connector.cpp">FILE_Connector.cpp</a></li> -<li><a href = "../ace/FILE_Connector.h">FILE_Connector.h</a></li> -<b><a href = "../man/html/ACE_FILE_Connector.html">[man page]</a></b> -<li><a href = "../ace/FILE_Connector.i">FILE_Connector.i</a></li> -<li><a href = "../ace/FILE_IO.cpp">FILE_IO.cpp</a></li> -<li><a href = "../ace/FILE_IO.h">FILE_IO.h</a></li> -<b><a href = "../man/html/ACE_FILE_IO.html">[man page]</a></b> -<li><a href = "../ace/FILE_IO.i">FILE_IO.i</a></li> -</ul> -</ul> -<b>[IPC_SAP]</b> -<ul> -<li><a href = "../ace/IPC_SAP.cpp">IPC_SAP.cpp</a></li> -<li><a href = "../ace/IPC_SAP.h">IPC_SAP.h</a></li> -<b><a href = "../man/html/ACE_IPC_SAP.html">[man page]</a></b> -<li><a href = "../ace/IPC_SAP.i">IPC_SAP.i</a></li> -<br> -<b>[Addr]</b> -<ul> -<li><a href = "../ace/Addr.cpp">Addr.cpp</a></li> -<li><a href = "../ace/Addr.h">Addr.h</a></li> -<b><a href = "../man/html/ACE_Addr.html">[man page]</a></b> -<li><a href = "../ace/Addr.i">Addr.i</a></li> -<li><a href = "../ace/DEV_Addr.cpp">DEV_Addr.cpp</a></li> -<li><a href = "../ace/DEV_Addr.h">DEV_Addr.h</a></li> -<b><a href = "../man/html/ACE_DEV_Addr.html">[man page]</a></b> -<li><a href = "../ace/DEV_Addr.i">DEV_Addr.i</a></li> -<li><a href = "../ace/FILE_Addr.cpp">FILE_Addr.cpp</a></li> -<li><a href = "../ace/FILE_Addr.h">FILE_Addr.h</a></li> -<b><a href = "../man/html/ACE_FILE_Addr.html">[man page]</a></b> -<li><a href = "../ace/FILE_Addr.i">FILE_Addr.i</a></li> -<li><a href = "../ace/INET_Addr.cpp">INET_Addr.cpp</a></li> -<li><a href = "../ace/INET_Addr.h">INET_Addr.h</a></li> -<b><a href = "../man/html/ACE_INET_Addr.html">[man page]</a></b> -<li><a href = "../ace/INET_Addr.i">INET_Addr.i</a></li> -<li><a href = "../ace/SPIPE_Addr.cpp">SPIPE_Addr.cpp</a></li> -<li><a href = "../ace/SPIPE_Addr.h">SPIPE_Addr.h</a></li> -<b><a href = "../man/html/ACE_SPIPE_Addr.html">[man page]</a></b> -<li><a href = "../ace/SPIPE_Addr.i">SPIPE_Addr.i</a></li> -<li><a href = "../ace/UNIX_Addr.cpp">UNIX_Addr.cpp</a></li> -<li><a href = "../ace/UNIX_Addr.h">UNIX_Addr.h</a></li> -<b><a href = "../man/html/ACE_UNIX_Addr.html">[man page]</a></b> -<li><a href = "../ace/UNIX_Addr.i">UNIX_Addr.i</a></li> -<li><a href = "../ace/UPIPE_Addr.h">UPIPE_Addr.h</a></li> -<b><a href = "../man/html/ACE_UPIPE_Addr.html">[man page]</a></b> -</ul> -<b>[FIFO_SAP]</b> -<ul> -<li><a href = "../ace/FIFO.cpp">FIFO.cpp</a></li> -<li><a href = "../ace/FIFO.h">FIFO.h</a></li> -<b><a href = "../man/html/ACE_FIFO.html">[man page]</a></b> -<li><a href = "../ace/FIFO.i">FIFO.i</a></li> -<li><a href = "../ace/FIFO_Recv.cpp">FIFO_Recv.cpp</a></li> -<li><a href = "../ace/FIFO_Recv.h">FIFO_Recv.h</a></li> -<b><a href = "../man/html/ACE_FIFO_Recv.html">[man page]</a></b> -<li><a href = "../ace/FIFO_Recv.i">FIFO_Recv.i</a></li> -<li><a href = "../ace/FIFO_Recv_Msg.cpp">FIFO_Recv_Msg.cpp</a></li> -<li><a href = "../ace/FIFO_Recv_Msg.h">FIFO_Recv_Msg.h</a></li> -<b><a href = "../man/html/ACE_FIFO_Recv_Msg.html">[man page]</a></b> -<li><a href = "../ace/FIFO_Recv_Msg.i">FIFO_Recv_Msg.i</a></li> -<li><a href = "../ace/FIFO_Send.cpp">FIFO_Send.cpp</a></li> -<li><a href = "../ace/FIFO_Send.h">FIFO_Send.h</a></li> -<b><a href = "../man/html/ACE_FIFO_Send.html">[man page]</a></b> -<li><a href = "../ace/FIFO_Send.i">FIFO_Send.i</a></li> -<li><a href = "../ace/FIFO_Send_Msg.cpp">FIFO_Send_Msg.cpp</a></li> -<li><a href = "../ace/FIFO_Send_Msg.h">FIFO_Send_Msg.h</a></li> -<b><a href = "../man/html/ACE_FIFO_Send_Msg.html">[man page]</a></b> -<li><a href = "../ace/FIFO_Send_Msg.i">FIFO_Send_Msg.i</a></li> -</ul> -<b>[SOCK_SAP]</b> -<ul> -<li><a href = "../ace/LOCK_SOCK_Acceptor.cpp">LOCK_SOCK_Acceptor.cpp</a></li> -<li><a href = "../ace/LOCK_SOCK_Acceptor.h">LOCK_SOCK_Acceptor.h</a></li> -<b><a href = "../man/html/ACE_LOCK_SOCK_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/LSOCK.cpp">LSOCK.cpp</a></li> -<li><a href = "../ace/LSOCK.h">LSOCK.h</a></li> -<b><a href = "../man/html/ACE_LSOCK.html">[man page]</a></b> -<li><a href = "../ace/LSOCK.i">LSOCK.i</a></li> -<li><a href = "../ace/LSOCK_Acceptor.cpp">LSOCK_Acceptor.cpp</a></li> -<li><a href = "../ace/LSOCK_Acceptor.h">LSOCK_Acceptor.h</a></li> -<b><a href = "../man/html/ACE_LSOCK_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/LSOCK_Acceptor.i">LSOCK_Acceptor.i</a></li> -<li><a href = "../ace/LSOCK_CODgram.cpp">LSOCK_CODgram.cpp</a></li> -<li><a href = "../ace/LSOCK_CODgram.h">LSOCK_CODgram.h</a></li> -<b><a href = "../man/html/ACE_LSOCK_CODgram.html">[man page]</a></b> -<li><a href = "../ace/LSOCK_CODgram.i">LSOCK_CODgram.i</a></li> -<li><a href = "../ace/LSOCK_Connector.cpp">LSOCK_Connector.cpp</a></li> -<li><a href = "../ace/LSOCK_Connector.h">LSOCK_Connector.h</a></li> -<b><a href = "../man/html/ACE_LSOCK_Connector.html">[man page]</a></b> -<li><a href = "../ace/LSOCK_Connector.i">LSOCK_Connector.i</a></li> -<li><a href = "../ace/LSOCK_Dgram.cpp">LSOCK_Dgram.cpp</a></li> -<li><a href = "../ace/LSOCK_Dgram.h">LSOCK_Dgram.h</a></li> -<b><a href = "../man/html/ACE_LSOCK_Dgram.html">[man page]</a></b> -<li><a href = "../ace/LSOCK_Dgram.i">LSOCK_Dgram.i</a></li> -<li><a href = "../ace/LSOCK_Stream.cpp">LSOCK_Stream.cpp</a></li> -<li><a href = "../ace/LSOCK_Stream.h">LSOCK_Stream.h</a></li> -<b><a href = "../man/html/ACE_LSOCK_Stream.html">[man page]</a></b> -<li><a href = "../ace/LSOCK_Stream.i">LSOCK_Stream.i</a></li> -<li><a href = "../ace/SOCK.cpp">SOCK.cpp</a></li> -<li><a href = "../ace/SOCK.h">SOCK.h</a></li> -<b><a href = "../man/html/ACE_SOCK.html">[man page]</a></b> -<li><a href = "../ace/SOCK.i">SOCK.i</a></li> -<li><a href = "../ace/SOCK_Acceptor.cpp">SOCK_Acceptor.cpp</a></li> -<li><a href = "../ace/SOCK_Acceptor.h">SOCK_Acceptor.h</a></li> -<b><a href = "../man/html/ACE_SOCK_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/SOCK_Acceptor.i">SOCK_Acceptor.i</a></li> -<li><a href = "../ace/SOCK_CODgram.cpp">SOCK_CODgram.cpp</a></li> -<li><a href = "../ace/SOCK_CODgram.h">SOCK_CODgram.h</a></li> -<b><a href = "../man/html/ACE_SOCK_CODgram.html">[man page]</a></b> -<li><a href = "../ace/SOCK_CODgram.i">SOCK_CODgram.i</a></li> -<li><a href = "../ace/SOCK_Connector.cpp">SOCK_Connector.cpp</a></li> -<li><a href = "../ace/SOCK_Connector.h">SOCK_Connector.h</a></li> -<b><a href = "../man/html/ACE_SOCK_Connector.html">[man page]</a></b> -<li><a href = "../ace/SOCK_Connector.i">SOCK_Connector.i</a></li> -<li><a href = "../ace/SOCK_Dgram.cpp">SOCK_Dgram.cpp</a></li> -<li><a href = "../ace/SOCK_Dgram.h">SOCK_Dgram.h</a></li> -<b><a href = "../man/html/ACE_SOCK_Dgram.html">[man page]</a></b> -<li><a href = "../ace/SOCK_Dgram.i">SOCK_Dgram.i</a></li> -<li><a href = "../ace/SOCK_Dgram_Bcast.cpp">SOCK_Dgram_Bcast.cpp</a></li> -<li><a href = "../ace/SOCK_Dgram_Bcast.h">SOCK_Dgram_Bcast.h</a></li> -<b><a href = "../man/html/ACE_SOCK_Dgram_Bcast.html">[man page]</a></b> -<li><a href = "../ace/SOCK_Dgram_Bcast.i">SOCK_Dgram_Bcast.i</a></li> -<li><a href = "../ace/SOCK_Dgram_Mcast.cpp">SOCK_Dgram_Mcast.cpp</a></li> -<li><a href = "../ace/SOCK_Dgram_Mcast.h">SOCK_Dgram_Mcast.h</a></li> -<b><a href = "../man/html/ACE_SOCK_Dgram_Mcast.html">[man page]</a></b> -<li><a href = "../ace/SOCK_Dgram_Mcast.i">SOCK_Dgram_Mcast.i</a></li> -<li><a href = "../ace/SOCK_IO.cpp">SOCK_IO.cpp</a></li> -<li><a href = "../ace/SOCK_IO.h">SOCK_IO.h</a></li> -<b><a href = "../man/html/ACE_SOCK_IO.html">[man page]</a></b> -<li><a href = "../ace/SOCK_IO.i">SOCK_IO.i</a></li> -<li><a href = "../ace/SOCK_Stream.cpp">SOCK_Stream.cpp</a></li> -<li><a href = "../ace/SOCK_Stream.h">SOCK_Stream.h</a></li> -<b><a href = "../man/html/ACE_SOCK_Stream.html">[man page]</a></b> -<li><a href = "../ace/SOCK_Stream.i">SOCK_Stream.i</a></li> -</ul> -<b>[SPIPE_SAP]</b> -<ul> -<li><a href = "../ace/SPIPE.cpp">SPIPE.cpp</a></li> -<li><a href = "../ace/SPIPE.h">SPIPE.h</a></li> -<b><a href = "../man/html/ACE_SPIPE.html">[man page]</a></b> -<li><a href = "../ace/SPIPE.i">SPIPE.i</a></li> -<li><a href = "../ace/SPIPE_Acceptor.cpp">SPIPE_Acceptor.cpp</a></li> -<li><a href = "../ace/SPIPE_Acceptor.h">SPIPE_Acceptor.h</a></li> -<b><a href = "../man/html/ACE_SPIPE_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/SPIPE_Acceptor.i">SPIPE_Acceptor.i</a></li> -<li><a href = "../ace/SPIPE_Connector.cpp">SPIPE_Connector.cpp</a></li> -<li><a href = "../ace/SPIPE_Connector.h">SPIPE_Connector.h</a></li> -<b><a href = "../man/html/ACE_SPIPE_Connector.html">[man page]</a></b> -<li><a href = "../ace/SPIPE_Connector.i">SPIPE_Connector.i</a></li> -<li><a href = "../ace/SPIPE_Stream.cpp">SPIPE_Stream.cpp</a></li> -<li><a href = "../ace/SPIPE_Stream.h">SPIPE_Stream.h</a></li> -<b><a href = "../man/html/ACE_SPIPE_Stream.html">[man page]</a></b> -<li><a href = "../ace/SPIPE_Stream.i">SPIPE_Stream.i</a></li> -</ul> -<b>[TLI_SAP]</b> -<ul> -<li><a href = "../ace/TLI.cpp">TLI.cpp</a></li> -<li><a href = "../ace/TLI.h">TLI.h</a></li> -<b><a href = "../man/html/ACE_TLI.html">[man page]</a></b> -<li><a href = "../ace/TLI.i">TLI.i</a></li> -<li><a href = "../ace/TLI_Acceptor.cpp">TLI_Acceptor.cpp</a></li> -<li><a href = "../ace/TLI_Acceptor.h">TLI_Acceptor.h</a></li> -<b><a href = "../man/html/ACE_TLI_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/TLI_Acceptor.i">TLI_Acceptor.i</a></li> -<li><a href = "../ace/TLI_Connector.cpp">TLI_Connector.cpp</a></li> -<li><a href = "../ace/TLI_Connector.h">TLI_Connector.h</a></li> -<b><a href = "../man/html/ACE_TLI_Connector.html">[man page]</a></b> -<li><a href = "../ace/TLI_Connector.i">TLI_Connector.i</a></li> -<li><a href = "../ace/TLI_Stream.cpp">TLI_Stream.cpp</a></li> -<li><a href = "../ace/TLI_Stream.h">TLI_Stream.h</a></li> -<b><a href = "../man/html/ACE_TLI_Stream.html">[man page]</a></b> -<li><a href = "../ace/TLI_Stream.i">TLI_Stream.i</a></li> -</ul> -</ul> -<b>[UPIPE_SAP]</b> -<ul> -<li><a href = "../ace/UPIPE_Acceptor.cpp">UPIPE_Acceptor.cpp</a></li> -<li><a href = "../ace/UPIPE_Acceptor.h">UPIPE_Acceptor.h</a></li> -<b><a href = "../man/html/ACE_UPIPE_Acceptor.html">[man page]</a></b> -<li><a href = "../ace/UPIPE_Acceptor.i">UPIPE_Acceptor.i</a></li> -<li><a href = "../ace/UPIPE_Connector.cpp">UPIPE_Connector.cpp</a></li> -<li><a href = "../ace/UPIPE_Connector.h">UPIPE_Connector.h</a></li> -<b><a href = "../man/html/ACE_UPIPE_Connector.html">[man page]</a></b> -<li><a href = "../ace/UPIPE_Connector.i">UPIPE_Connector.i</a></li> -<li><a href = "../ace/UPIPE_Stream.cpp">UPIPE_Stream.cpp</a></li> -<li><a href = "../ace/UPIPE_Stream.h">UPIPE_Stream.h</a></li> -<b><a href = "../man/html/ACE_UPIPE_Stream.html">[man page]</a></b> -<li><a href = "../ace/UPIPE_Stream.i">UPIPE_Stream.i</a></li> -</ul> -<b>[Misc]</b> -<ul> -<li><a href = "../ace/IOStream.cpp">IOStream.cpp</a></li> -<li><a href = "../ace/IOStream.h">IOStream.h</a></li> -<b><a href = "../man/html/ACE_IOStream.html">[man page]</a></b> -<li><a href = "../ace/IOStream_T.cpp">IOStream_T.cpp</a></li> -<li><a href = "../ace/IOStream_T.h">IOStream_T.h</a></li> -<b><a href = "../man/html/ACE_IOStream_T.html">[man page]</a></b> -<li><a href = "../ace/IOStream_T.i">IOStream_T.i</a></li> -<li><a href = "../ace/Pipe.cpp">Pipe.cpp</a></li> -<li><a href = "../ace/Pipe.h">Pipe.h</a></li> -<b><a href = "../man/html/ACE_Pipe.html">[man page]</a></b> -<li><a href = "../ace/Pipe.i">Pipe.i</a></li> -<li><a href = "../ace/Signal.cpp">Signal.cpp</a></li> -<li><a href = "../ace/Signal.h">Signal.h</a></li> -<li><a href = "../ace/Signal.i">Signal.i</a></li> -</ul> -</ul> -<b>[Logging and Tracing]</b> -<ul> -<li><a href = "../ace/Dump.cpp">Dump.cpp</a></li> -<li><a href = "../ace/Dump.h">Dump.h</a></li> -<li><a href = "../ace/Dump_T.cpp">Dump_T.cpp</a></li> -<li><a href = "../ace/Dump_T.h">Dump_T.h</a></li> -<li><a href = "../ace/Log_Msg.cpp">Log_Msg.cpp</a></li> -<li><a href = "../ace/Log_Msg.h">Log_Msg.h</a></li> -<b><a href = "../man/html/ACE_Log_Msg.html">[man page]</a></b> -<li><a href = "../ace/Log_Msg.i">Log_Msg.i</a></li> -<li><a href = "../ace/Log_Priority.h">Log_Priority.h</a></li> -<li><a href = "../ace/Log_Record.cpp">Log_Record.cpp</a></li> -<li><a href = "../ace/Log_Record.h">Log_Record.h</a></li> -<b><a href = "../man/html/ACE_Log_Record.html">[man page]</a></b> -<li><a href = "../ace/Log_Record.i">Log_Record.i</a></li> -<li><a href = "../ace/Trace.cpp">Trace.cpp</a></li> -<li><a href = "../ace/Trace.h">Trace.h</a></li> -<b><a href = "../man/html/ACE_Trace.html">[man page]</a></b> -<li><a href = "../ace/Trace.i">Trace.i</a></li> -</ul> -<b>[Memory]</b> -<ul> -<b>[Mem_Map]</b> -<ul> -<li><a href = "../ace/Mem_Map.cpp">Mem_Map.cpp</a></li> -<li><a href = "../ace/Mem_Map.h">Mem_Map.h</a></li> -<b><a href = "../man/html/ACE_Mem_Map.html">[man page]</a></b> -<li><a href = "../ace/Mem_Map.i">Mem_Map.i</a></li> -</ul> -<b>[Shared_Malloc]</b> -<ul> -<li><a href = "../ace/Malloc.cpp">Malloc.cpp</a></li> -<li><a href = "../ace/Malloc.h">Malloc.h</a></li> -<b><a href = "../man/html/ACE_Malloc.html">[man page]</a></b> -<li><a href = "../ace/Malloc.i">Malloc.i</a></li> -<li><a href = "../ace/Malloc_T.cpp">Malloc_T.cpp</a></li> -<li><a href = "../ace/Malloc_T.h">Malloc_T.h</a></li> -<li><a href = "../ace/Malloc_T.i">Malloc_T.i</a></li> -<li><a href = "../ace/Memory_Pool.cpp">Memory_Pool.cpp</a></li> -<li><a href = "../ace/Memory_Pool.h">Memory_Pool.h</a></li> -<li><a href = "../ace/Memory_Pool.i">Memory_Pool.i</a></li> -</ul> -<b>[Shared_Memory]</b> -<ul> -<li><a href = "../ace/Shared_Memory.h">Shared_Memory.h</a></li> -<b><a href = "../man/html/ACE_Shared_Memory.html">[man page]</a></b> -<li><a href = "../ace/Shared_Memory_MM.cpp">Shared_Memory_MM.cpp</a></li> -<li><a href = "../ace/Shared_Memory_MM.h">Shared_Memory_MM.h</a></li> -<b><a href = "../man/html/ACE_Shared_Memory_MM.html">[man page]</a></b> -<li><a href = "../ace/Shared_Memory_MM.i">Shared_Memory_MM.i</a></li> -<li><a href = "../ace/Shared_Memory_SV.cpp">Shared_Memory_SV.cpp</a></li> -<li><a href = "../ace/Shared_Memory_SV.h">Shared_Memory_SV.h</a></li> -<b><a href = "../man/html/ACE_Shared_Memory_SV.html">[man page]</a></b> -<li><a href = "../ace/Shared_Memory_SV.i">Shared_Memory_SV.i</a></li> -</ul> -<b>[Utils]</b> -<ul> -<li><a href = "../ace/Obstack.cpp">Obstack.cpp</a></li> -<li><a href = "../ace/Obstack.h">Obstack.h</a></li> -<b><a href = "../man/html/ACE_Obstack.html">[man page]</a></b> -<li><a href = "../ace/Read_Buffer.cpp">Read_Buffer.cpp</a></li> -<li><a href = "../ace/Read_Buffer.h">Read_Buffer.h</a></li> -<b><a href = "../man/html/ACE_Read_Buffer.html">[man page]</a></b> -<li><a href = "../ace/Read_Buffer.i">Read_Buffer.i</a></li> -</ul> -</ul> -<b>[Misc]</b> -<ul> -<li><a href = "../ace/ARGV.cpp">ARGV.cpp</a></li> -<li><a href = "../ace/ARGV.h">ARGV.h</a></li> -<b><a href = "../man/html/ACE_ARGV.html">[man page]</a></b> -<li><a href = "../ace/ARGV.i">ARGV.i</a></li> -<li><a href = "../ace/Auto_Ptr.cpp">Auto_Ptr.cpp</a></li> -<li><a href = "../ace/Auto_Ptr.h">Auto_Ptr.h</a></li> -<li><a href = "../ace/Auto_Ptr.i">Auto_Ptr.i</a></li> -<li><a href = "../ace/Date_Time.cpp">Date_Time.cpp</a></li> -<li><a href = "../ace/Date_Time.h">Date_Time.h</a></li> -<b><a href = "../man/html/ACE_Date_Time.html">[man page]</a></b> -<li><a href = "../ace/Date_Time.i">Date_Time.i</a></li> -<li><a href = "../ace/Dynamic.cpp">Dynamic.cpp</a></li> -<li><a href = "../ace/Dynamic.h">Dynamic.h</a></li> -<b><a href = "../man/html/ACE_Dynamic.html">[man page]</a></b> -<li><a href = "../ace/Dynamic.i">Dynamic.i</a></li> -<li><a href = "../ace/Get_Opt.cpp">Get_Opt.cpp</a></li> -<li><a href = "../ace/Get_Opt.h">Get_Opt.h</a></li> -<b><a href = "../man/html/ACE_Get_Opt.html">[man page]</a></b> -<li><a href = "../ace/Get_Opt.i">Get_Opt.i</a></li> -<li><a href = "../ace/Registry.cpp">Registry.cpp</a></li> -<li><a href = "../ace/Registry.h">Registry.h</a></li> -<b><a href = "../man/html/ACE_Registry.html">[man page]</a></b> -<li><a href = "../ace/Singleton.cpp">Singleton.cpp</a></li> -<li><a href = "../ace/Singleton.h">Singleton.h</a></li> -<b><a href = "../man/html/ACE_Singleton.html">[man page]</a></b> -<li><a href = "../ace/Singleton.i">Singleton.i</a></li> -<li><a href = "../ace/System_Time.cpp">System_Time.cpp</a></li> -<li><a href = "../ace/System_Time.h">System_Time.h</a></li> -<b><a href = "../man/html/ACE_System_Time.html">[man page]</a></b> -</ul> -<b>[Name_Service]</b> -<ul> -<li><a href = "../ace/Local_Name_Space.cpp">Local_Name_Space.cpp</a></li> -<li><a href = "../ace/Local_Name_Space.h">Local_Name_Space.h</a></li> -<b><a href = "../man/html/ACE_Local_Name_Space.html">[man page]</a></b> -<li><a href = "../ace/Local_Name_Space_T.cpp">Local_Name_Space_T.cpp</a></li> -<li><a href = "../ace/Local_Name_Space_T.h">Local_Name_Space_T.h</a></li> -<b><a href = "../man/html/ACE_Name_Options.html">[man page]</a></b> -<li><a href = "../ace/Name_Proxy.cpp">Name_Proxy.cpp</a></li> -<li><a href = "../ace/Name_Proxy.h">Name_Proxy.h</a></li> -<b><a href = "../man/html/ACE_Name_Proxy.html">[man page]</a></b> -<li><a href = "../ace/Name_Request_Reply.cpp">Name_Request_Reply.cpp</a></li> -<li><a href = "../ace/Name_Request_Reply.h">Name_Request_Reply.h</a></li> -<li><a href = "../ace/Name_Space.cpp">Name_Space.cpp</a></li> -<li><a href = "../ace/Name_Space.h">Name_Space.h</a></li> -<b><a href = "../man/html/ACE_Name_Space.html">[man page]</a></b> -<li><a href = "../ace/Naming_Context.cpp">Naming_Context.cpp</a></li> -<li><a href = "../ace/Naming_Context.h">Naming_Context.h</a></li> -<b><a href = "../man/html/ACE_Naming_Context.html">[man page]</a></b> -<li><a href = "../ace/Registry_Name_Space.cpp">Registry_Name_Space.cpp</a></li> -<li><a href = "../ace/Registry_Name_Space.h">Registry_Name_Space.h</a></li> -<b><a href = "../man/html/ACE_Registry_Name_Space.html">[man page]</a></b> -<li><a href = "../ace/Remote_Name_Space.cpp">Remote_Name_Space.cpp</a></li> -<li><a href = "../ace/Remote_Name_Space.h">Remote_Name_Space.h</a></li> -<b><a href = "../man/html/ACE_Remote_Name_Space.html">[man page]</a></b> -</ul> -<b>[OS Adapters]</b> -<ul> -<li><a href = "../ace/ACE.cpp">ACE.cpp</a></li> -<li><a href = "../ace/ACE.h">ACE.h</a></li> -<b><a href = "../man/html/ACE.html">[man page]</a></b> -<li><a href = "../ace/ACE.i">ACE.i</a></li> -<li><a href = "../ace/OS.cpp">OS.cpp</a></li> -<li><a href = "../ace/OS.h">OS.h</a></li> -<b><a href = "../man/html/ACE_OS.html">[man page]</a></b> -<li><a href = "../ace/OS.i">OS.i</a></li> -</ul> -<b>[Reactor]</b> -<ul> -<li><a href = "../ace/Event_Handler.cpp">Event_Handler.cpp</a></li> -<li><a href = "../ace/Event_Handler.h">Event_Handler.h</a></li> -<b><a href = "../man/html/ACE_Event_Handler.html">[man page]</a></b> -<li><a href = "../ace/Event_Handler.i">Event_Handler.i</a></li> -<li><a href = "../ace/Event_Handler_T.cpp">Event_Handler_T.cpp</a></li> -<li><a href = "../ace/Event_Handler_T.h">Event_Handler_T.h</a></li> -<b><a href = "../man/html/ACE_Event_Handler_T.html">[man page]</a></b> -<li><a href = "../ace/Event_Handler_T.i">Event_Handler_T.i</a></li> -<li><a href = "../ace/Handle_Set.cpp">Handle_Set.cpp</a></li> -<li><a href = "../ace/Handle_Set.h">Handle_Set.h</a></li> -<b><a href = "../man/html/ACE_Handle_Set.html">[man page]</a></b> -<li><a href = "../ace/Handle_Set.i">Handle_Set.i</a></li> -<li><a href = "../ace/Priority_Reactor.cpp">Priority_Reactor.cpp</a></li> -<li><a href = "../ace/Priority_Reactor.i">Priority_Reactor.i</a></li> -<li><a href = "../ace/Priority_Reactor.h">Priority_Reactor.h</a></li> -<b><a href = "../man/html/ACE_Priority_Reactor.html">[man page]</a></b> -<li><a href = "../ace/Proactor.h">Proactor.h</a></li> -<b><a href = "../man/html/ACE_Proactor.html">[man page]</a></b> -<li><a href = "../ace/Proactor.i">Proactor.i</a></li> -<li><a href = "../ace/Proactor.cpp">Proactor.cpp</a></li> -<li><a href = "../ace/Reactor.cpp">Reactor.cpp</a></li> -<li><a href = "../ace/Reactor.h">Reactor.h</a></li> -<b><a href = "../man/html/ACE_Reactor.html">[man page]</a></b> -<li><a href = "../ace/Reactor.i">Reactor.i</a></li> -<b><a href = "../man/html/ACE_ReactorEx.html">[man page]</a></b> -<li><a href = "../ace/Reactor_Impl.h">Reactor_Impl.h</a></li> -<b><a href = "../man/html/ACE_Reactor_Impl.html">[man page]</a></b> -<li><a href = "../ace/Select_Reactor.cpp">Select_Reactor.cpp</a></li> -<li><a href = "../ace/Select_Reactor.h">Select_Reactor.h</a></li> -<b><a href = "../man/html/ACE_Select_Reactor.html">[man page]</a></b> -<li><a href = "../ace/Select_Reactor.i">Select_Reactor.i</a></li> -<li><a href = "../ace/WFMO_Reactor.cpp">WFMO_Reactor.cpp</a></li> -<li><a href = "../ace/WFMO_Reactor.h">WFMO_Reactor.h</a></li> -<b><a href = "../man/html/ACE_WFMO_Reactor.html">[man page]</a></b> -<li><a href = "../ace/WFMO_Reactor.i">WFMO_Reactor.i</a></li> -<li><a href = "../ace/XtReactor.cpp">XtReactor.cpp</a></li> -<li><a href = "../ace/XtReactor.h">XtReactor.h</a></li> -<b><a href = "../man/html/ACE_XtReactor.html">[man page]</a></b> -</ul> -<b>[Service_Configurator]</b> -<ul> -<li><a href = "../ace/DLL.cpp">DLL.cpp</a></li> -<li><a href = "../ace/DLL.h">DLL.h</a></li> -<b><a href = "../man/html/ACE_DLL.html">[man page]</a></b> -<li><a href = "../ace/Parse_Node.cpp">Parse_Node.cpp</a></li> -<li><a href = "../ace/Parse_Node.h">Parse_Node.h</a></li> -<b><a href = "../man/html/ACE_Parse_Node.html">[man page]</a></b> -<li><a href = "../ace/Parse_Node.i">Parse_Node.i</a></li> -<li><a href = "../ace/Service_Config.cpp">Service_Config.cpp</a></li> -<li><a href = "../ace/Service_Config.h">Service_Config.h</a></li> -<b><a href = "../man/html/ACE_Service_Config.html">[man page]</a></b> -<li><a href = "../ace/Service_Config.i">Service_Config.i</a></li> -<li><a href = "../ace/Service_Manager.cpp">Service_Manager.cpp</a></li> -<li><a href = "../ace/Service_Manager.h">Service_Manager.h</a></li> -<b><a href = "../man/html/ACE_Service_Manager.html">[man page]</a></b> -<li><a href = "../ace/Service_Manager.i">Service_Manager.i</a></li> -<li><a href = "../ace/Service_Object.cpp">Service_Object.cpp</a></li> -<li><a href = "../ace/Service_Object.h">Service_Object.h</a></li> -<b><a href = "../man/html/ACE_Service_Object.html">[man page]</a></b> -<li><a href = "../ace/Service_Object.i">Service_Object.i</a></li> -<li><a href = "../ace/Service_Repository.cpp">Service_Repository.cpp</a></li> -<li><a href = "../ace/Service_Repository.h">Service_Repository.h</a></li> -<b><a href = "../man/html/ACE_Service_Repository.html">[man page]</a></b> -<li><a href = "../ace/Service_Repository.i">Service_Repository.i</a></li> -<li><a href = "../ace/Service_Types.cpp">Service_Types.cpp</a></li> -<li><a href = "../ace/Service_Types.i">Service_Types.i</a></li> -<li><a href = "../ace/Service_Types.h">Service_Types.h</a></li> -<li><a href = "../ace/Shared_Object.cpp">Shared_Object.cpp</a></li> -<li><a href = "../ace/Shared_Object.h">Shared_Object.h</a></li> -<b><a href = "../man/html/ACE_Shared_Object.html">[man page]</a></b> -<li><a href = "../ace/Shared_Object.i">Shared_Object.i</a></li> -<li><a href = "../ace/Svc_Conf.h">Svc_Conf.h</a></li> -<li><a href = "../ace/Svc_Conf_l.cpp">Svc_Conf_l.cpp</a></li> -<li><a href = "../ace/Svc_Conf_y.cpp">Svc_Conf_y.cpp</a></li> -<li><a href = "../ace/Svc_Conf_Tokens.h">Svc_Conf_Tokens.h</a></li> -</ul> -<b>[Streams]</b> -<ul> -<li><a href = "../ace/IO_Cntl_Msg.cpp">IO_Cntl_Msg.cpp</a></li> -<li><a href = "../ace/IO_Cntl_Msg.h">IO_Cntl_Msg.h</a></li> -<b><a href = "../man/html/ACE_IO_Cntl_Msg.html">[man page]</a></b> -<li><a href = "../ace/IO_Cntl_Msg.i">IO_Cntl_Msg.i</a></li> -<li><a href = "../ace/Message_Block.cpp">Message_Block.cpp</a></li> -<li><a href = "../ace/Message_Block.h">Message_Block.h</a></li> -<b><a href = "../man/html/ACE_Message_Block.html">[man page]</a></b> -<li><a href = "../ace/Message_Block.i">Message_Block.i</a></li> -<li><a href = "../ace/Message_Queue.cpp">Message_Queue.cpp</a></li> -<li><a href = "../ace/Message_Queue.h">Message_Queue.h</a></li> -<b><a href = "../man/html/ACE_Message_Queue.html">[man page]</a></b> -<li><a href = "../ace/Message_Queue.i">Message_Queue.i</a></li> -<li><a href = "../ace/Message_Queue_T.cpp">Message_Queue_T.cpp</a></li> -<li><a href = "../ace/Message_Queue_T.h">Message_Queue_T.h</a></li> -<li><a href = "../ace/Message_Queue_T.i">Message_Queue_T.i</a></li> -<li><a href = "../ace/Module.cpp">Module.cpp</a></li> -<li><a href = "../ace/Module.h">Module.h</a></li> -<b><a href = "../man/html/ACE_Module.html">[man page]</a></b> -<li><a href = "../ace/Module.i">Module.i</a></li> -<li><a href = "../ace/Multiplexor.cpp">Multiplexor.cpp</a></li> -<li><a href = "../ace/Multiplexor.h">Multiplexor.h</a></li> -<b><a href = "../man/html/ACE_Multiplexor.html">[man page]</a></b> -<li><a href = "../ace/Multiplexor.i">Multiplexor.i</a></li> -<li><a href = "../ace/Stream.cpp">Stream.cpp</a></li> -<li><a href = "../ace/Stream.h">Stream.h</a></li> -<b><a href = "../man/html/ACE_Stream.html">[man page]</a></b> -<li><a href = "../ace/Stream.i">Stream.i</a></li> -<li><a href = "../ace/Stream_Modules.cpp">Stream_Modules.cpp</a></li> -<li><a href = "../ace/Stream_Modules.h">Stream_Modules.h</a></li> -<li><a href = "../ace/Stream_Modules.i">Stream_Modules.i</a></li> -<li><a href = "../ace/Task.cpp">Task.cpp</a></li> -<li><a href = "../ace/Task.h">Task.h</a></li> -<b><a href = "../man/html/ACE_Task.html">[man page]</a></b> -<li><a href = "../ace/Task.i">Task.i</a></li> -<li><a href = "../ace/Task_T.cpp">Task_T.cpp</a></li> -<li><a href = "../ace/Task_T.h">Task_T.h</a></li> -<li><a href = "../ace/Task_T.i">Task_T.i</a></li> -</ul> -<b>[System_V_IPC]</b> -<ul> -<b>[System_V_Message_Queues]</b> -<ul> -<li><a href = "../ace/SV_Message.cpp">SV_Message.cpp</a></li> -<li><a href = "../ace/SV_Message.h">SV_Message.h</a></li> -<b><a href = "../man/html/ACE_SV_Message.html">[man page]</a></b> -<li><a href = "../ace/SV_Message.i">SV_Message.i</a></li> -<li><a href = "../ace/SV_Message_Queue.cpp">SV_Message_Queue.cpp</a></li> -<li><a href = "../ace/SV_Message_Queue.h">SV_Message_Queue.h</a></li> -<b><a href = "../man/html/ACE_SV_Message_Queue.html">[man page]</a></b> -<li><a href = "../ace/SV_Message_Queue.i">SV_Message_Queue.i</a></li> -<li><a href = "../ace/Typed_SV_Message.cpp">Typed_SV_Message.cpp</a></li> -<li><a href = "../ace/Typed_SV_Message.h">Typed_SV_Message.h</a></li> -<b><a href = "../man/html/ACE_Typed_SV_Message.html">[man page]</a></b> -<li><a href = "../ace/Typed_SV_Message.i">Typed_SV_Message.i</a></li> -<li><a href = "../ace/Typed_SV_Message_Queue.cpp">Typed_SV_Message_Queue.cpp</a></ -li> -<li><a href = "../ace/Typed_SV_Message_Queue.h">Typed_SV_Message_Queue.h</a></li> -<b><a href = "../man/html/ACE_Typed_SV_Message_Queue.html">[man page]</a></b> -<li><a href = "../ace/Typed_SV_Message_Queue.i">Typed_SV_Message_Queue.i</a></li> -</ul> -<b>[System_V_Semaphores]</b> -<ul> -<li><a href = "../ace/SV_Semaphore_Complex.cpp">SV_Semaphore_Complex.cpp</a></li> -<li><a href = "../ace/SV_Semaphore_Complex.h">SV_Semaphore_Complex.h</a></li> -<b><a href = "../man/html/ACE_SV_Semaphore_Complex.html">[man page]</a></b> -<li><a href = "../ace/SV_Semaphore_Complex.i">SV_Semaphore_Complex.i</a></li> -<li><a href = "../ace/SV_Semaphore_Simple.cpp">SV_Semaphore_Simple.cpp</a></li> -<li><a href = "../ace/SV_Semaphore_Simple.h">SV_Semaphore_Simple.h</a></li> -<b><a href = "../man/html/ACE_SV_Semaphore_Simple.html">[man page]</a></b> -<li><a href = "../ace/SV_Semaphore_Simple.i">SV_Semaphore_Simple.i</a></li> -</ul> -<b>[System_V_Shared_Memory]</b> -<ul> -<li><a href = "../ace/SV_Shared_Memory.cpp">SV_Shared_Memory.cpp</a></li> -<li><a href = "../ace/SV_Shared_Memory.h">SV_Shared_Memory.h</a></li> -<b><a href = "../man/html/ACE_SV_Shared_Memory.html">[man page]</a></b> -<li><a href = "../ace/SV_Shared_Memory.i">SV_Shared_Memory.i</a></li> -</ul> -</ul> -<b>[Timers]</b> -<ul> -<li><a href = "../ace/High_Res_Timer.cpp">High_Res_Timer.cpp</a></li> -<li><a href = "../ace/High_Res_Timer.h">High_Res_Timer.h</a></li> -<b><a href = "../man/html/ACE_High_Res_Timer.html">[man page]</a></b> -<li><a href = "../ace/High_Res_Timer.i">High_Res_Timer.i</a></li> -<li><a href = "../ace/Profile_Timer.cpp">Profile_Timer.cpp</a></li> -<li><a href = "../ace/Profile_Timer.h">Profile_Timer.h</a></li> -<b><a href = "../man/html/ACE_Profile_Timer.html">[man page]</a></b> -<li><a href = "../ace/Profile_Timer.i">Profile_Timer.i</a></li> -<li><a href = "../ace/Time_Request_Reply.cpp">Time_Request_Reply.cpp</a></li> -<li><a href = "../ace/Time_Request_Reply.h">Time_Request_Reply.h</a></li> -<li><a href = "../ace/Time_Value.h">Time_Value.h</a></li> -<b><a href = "../man/html/ACE_Time_Value.html">[man page]</a></b> -<li><a href = "../ace/Timer_Hash.cpp">Timer_Hash.cpp</a></li> -<li><a href = "../ace/Timer_Hash.h">Timer_Hash.h</a></li> -<li><a href = "../ace/Timer_Hash_T.cpp">Timer_Hash_T.cpp</a></li> -<li><a href = "../ace/Timer_Hash_T.h">Timer_Hash_T.h</a></li> -<b><a href = "../man/html/ACE_Timer_Hash_T.html">[man page]</a></b> -<li><a href = "../ace/Timer_Heap.cpp">Timer_Heap.cpp</a></li> -<li><a href = "../ace/Timer_Heap.h">Timer_Heap.h</a></li> -<b><a href = "../man/html/ACE_Timer_Heap.html">[man page]</a></b> -<li><a href = "../ace/Timer_Heap_T.cpp">Timer_Heap_T.cpp</a></li> -<li><a href = "../ace/Timer_Heap_T.h">Timer_Heap_T.h</a></li> -<b><a href = "../man/html/ACE_Timer_Heap_T.html">[man page]</a></b> -<li><a href = "../ace/Timer_List.cpp">Timer_List.cpp</a></li> -<li><a href = "../ace/Timer_List.h">Timer_List.h</a></li> -<b><a href = "../man/html/ACE_Timer_List.html">[man page]</a></b> -<li><a href = "../ace/Timer_List_T.cpp">Timer_List_T.cpp</a></li> -<li><a href = "../ace/Timer_List_T.h">Timer_List_T.h</a></li> -<b><a href = "../man/html/ACE_Timer_List_T.html">[man page]</a></b> -<li><a href = "../ace/Timer_Queue.cpp">Timer_Queue.cpp</a></li> -<li><a href = "../ace/Timer_Queue.h">Timer_Queue.h</a></li> -<b><a href = "../man/html/ACE_Timer_Queue.html">[man page]</a></b> -<li><a href = "../ace/Timer_Queue.i">Timer_Queue.i</a></li> -<li><a href = "../ace/Timer_Queue_Adapters.cpp">Timer_Queue_Adapters.cpp</a></li> -<li><a href = "../ace/Timer_Queue_Adapters.h">Timer_Queue_Adapters.h</a></li> -<li><a href = "../ace/Timer_Queue_Adapters.i">Timer_Queue_Adapters.i</a></li> -<li><a href = "../ace/Timer_Queue_T.cpp">Timer_Queue_T.cpp</a></li> -<li><a href = "../ace/Timer_Queue_T.h">Timer_Queue_T.h</a></li> -<b><a href = "../man/html/ACE_Timer_Queue_T.html">[man page]</a></b> -<li><a href = "../ace/Timer_Queue_T.i">Timer_Queue_T.i</a></li> -<li><a href = "../ace/Timer_Wheel.cpp">Timer_Wheel.cpp</a></li> -<li><a href = "../ace/Timer_Wheel.h">Timer_Wheel.h</a></li> -<li><a href = "../ace/Timer_Wheel_T.cpp">Timer_Wheel_T.cpp</a></li> -<li><a href = "../ace/Timer_Wheel_T.h">Timer_Wheel_T.h</a></li> -<b><a href = "../man/html/ACE_Timer_Wheel_T.html">[man page]</a></b> -</ul> -<b>[Token_Service]</b> -<ul> -<li><a href = "../ace/Local_Tokens.cpp">Local_Tokens.cpp</a></li> -<li><a href = "../ace/Local_Tokens.h">Local_Tokens.h</a></li> -<li><a href = "../ace/Local_Tokens.i">Local_Tokens.i</a></li> -<li><a href = "../ace/Remote_Tokens.cpp">Remote_Tokens.cpp</a></li> -<li><a href = "../ace/Remote_Tokens.h">Remote_Tokens.h</a></li> -<li><a href = "../ace/Remote_Tokens.i">Remote_Tokens.i</a></li> -<li><a href = "../ace/Token_Collection.cpp">Token_Collection.cpp</a></li> -<li><a href = "../ace/Token_Collection.h">Token_Collection.h</a></li> -<b><a href = "../man/html/ACE_Token_Collection.html">[man page]</a></b> -<li><a href = "../ace/Token_Collection.i">Token_Collection.i</a></li> -<li><a href = "../ace/Token_Manager.cpp">Token_Manager.cpp</a></li> -<li><a href = "../ace/Token_Manager.h">Token_Manager.h</a></li> -<b><a href = "../man/html/ACE_Token_Manager.html">[man page]</a></b> -<li><a href = "../ace/Token_Manager.i">Token_Manager.i</a></li> -<li><a href = "../ace/Token_Request_Reply.cpp">Token_Request_Reply.cpp</a></li> -<li><a href = "../ace/Token_Request_Reply.h">Token_Request_Reply.h</a></li> -<li><a href = "../ace/Token_Request_Reply.i">Token_Request_Reply.i</a></li> -<li><a href = "../ace/Token_Invariants.h">Token_Invariants.h</a></li> -<li><a href = "../ace/Token_Invariants.i">Token_Invariants.i</a></li> -<li><a href = "../ace/Token_Invariants.cpp">Token_Invariants.cpp</a></li> -</ul> -</ul> - -<P><HR><P> - -Back to the <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ACE-documentation.html">ACE -documentation</A> page. - -<!--#include virtual="/~schmidt/cgi-sig.html" --> -</body> -</html> diff --git a/docs/ACE-guidelines.html b/docs/ACE-guidelines.html deleted file mode 100644 index 12fb1c2afc8..00000000000 --- a/docs/ACE-guidelines.html +++ /dev/null @@ -1,863 +0,0 @@ -<!-- $Id$ --> - -<html> - <head> - <title>ACE Software Development Guidelines</title> - <link rev=made href="mailto:levine@cs.wustl.edu"> - </head> - -<BODY text = "#000000" -link="#000fff" -vlink="#ff0f0f" -bgcolor="#ffffff"> - -<hr> - <h3>ACE Software Development Guidelines</h3> - -<ul> - <li><strong>General</strong><p> - <ul> - <li>Every text file must end with a newline.<p> - - <li>Use spaces instead of tabs, except in Makefiles. Emacs users - can add this to their <strong>.emacs</strong>: - - <pre>(setq-default indent-tabs-mode nil)</pre></p> - - Microsoft Visual C++ users should do the following: - - <pre> - Choose: Tools -- Options -- Tabs - Then Set: "Tab size" to 8 and "Indent size" to 2, and - indent using spaces. - </pre><p> - - <li>If you add a comment to code that is directed to, or - requires the attention of, a particular individual: - <strong>SEND EMAIL TO THAT INDIVIDUAL!</strong>.<p> - - <li>Every program should have a ``usage'' message. It should be - printed out if erroneous command line arguments, or a - <strong><code>-?</code></strong> command line argument, are - provided to the program.<p> - - <li>The program <strong><code>main</code></strong> function must - always be declared with arguments, <em>e.g.</em>, - <pre> - int - main (int argc, char *argv[]) - { - [...] - - return 0; - } - </pre><p> - - If you don't use the <code>argc</code> and/or <code>argv</code> - arguments, don't declare them, <em>e.g.</em>, - <pre> - int - main (int, char *[]) - { - [...] - - return 0; - } - </pre><p> - - Please declare the second argument as <code>char *[]</code> - instead of <code>char **</code>. Ancient versions of MSC - complained about <code>char **</code>; I've never seen a - C++ compiler complain about <code>char *[]</code>.<p> - - <code>main</code> must also return 0 on successful - termination, and non-zero otherwise.<p> - - <li>Avoid use of floating point types (float and double) and operations - unless absolutely necessary. Not all ACE platforms support them. - Therefore, wherever they are used, ACE_LACKS_FLOATING_POINT - conditional code must be also be used.<p> - </ul> - - <li><strong>Code Documentation</strong><p> - <ul> - <li>Use comments and whitespace (:-) liberally. Comments - should consist of complete sentences, <em>i.e.</em>, start - with a capital letter and end with a period.<p> - - <li>Insert a CVS/RCS keyword string at the top of every source file, - Makefile, config file, <em>etc</em>. For C++ files, it is: - <pre> - // $<!-- -->Id$ - </pre> - It is not necessary to fill in the fields of the keyword string, - or modify them when you edit a file that already has one. CVS - does that automatically when you checkout or update the file.<p> - - To insert that string at the top of a file: - <pre> - perl -pi -e \ - 'if (! $o) {printf "// \$<!-- -->Id\$\n\n";}; $o = 1;' <em>file</em> - </pre><p> - - <li>Comments, especially in header files, must follow the - <a href=http://www.dscpl.com.au>OSE</a> Tools format requirements. - Please see the ``Classinfo Tools'' section of the - <a href=http://www.dscpl.com.au>OSE</a> ``Tools Manual'' - for these requirements.<p> - - </ul> - - <li><strong>Preprocessor</strong><p> - <ul> - <li>Never #include standard headers directly, except in a few - specific ACE files, <em>e.g.</em>, OS.h and stdcpp.h. Let - those files #include the correct headers. If you do not do - this, your code will not compile with the Standard C++ Library.<p> - - <li>Always follow a preprocessor <strong><code>#endif</code></strong> - with a <strong><code>/* */</code></strong> C-style comment. It - should correspond to the condition in the matching - <strong><code>#if</code></strong> directive. For example, - <pre> - #if defined (ACE_HAS_THREADS) - # if defined (ACE_HAS_STHREADS) - # include /**/ <synch.h> - # include /**/ <thread.h> - # define ACE_SCOPE_PROCESS P_PID - # define ACE_SCOPE_LWP P_LWPID - # define ACE_SCOPE_THREAD (ACE_SCOPE_LWP + 1) - # else - # define ACE_SCOPE_PROCESS 0 - # define ACE_SCOPE_LWP 1 - # define ACE_SCOPE_THREAD 2 - # endif /* ACE_HAS_STHREADS */ - #endif /* ACE_HAS_THREADS */ - </pre><p> - - <li>Always insert a <strong><code>/**/</code></strong> between an - <strong><code>#include</code></strong> and - <strong><code>filename</code></strong>, as shown in the above - example. This avoids dependency problems with Visual C++.<p> - - <li>Be very careful with names of macros and enum values. It's - always best to prefix them with something like <code>ACE_</code> - or <code>TAO_</code>. There are too many system headers out - there that #define <code>OK</code>, <code>SUCCESS</code>, - <code>ERROR</code>, and so on.<p> - - <li>Try to centralize <code>#ifdefs</code> with <code>typedefs</code> - and <code>#defines</code>. For example, use this: - <pre> - #if defined(ACE_PSOS) - typedef long ACE_NETIF_TYPE; - # define ACE_DEFAULT_NETIF 0 - #else /* ! ACE_PSOS */ - typedef const ASYS_TCHAR* ACE_NETIF_TYPE; - # define ACE_DEFAULT_NETIF ASYS_TEXT("le0") - #endif /* ! ACE_PSOS */ - </pre><p> - - instead of: - - <pre><p> - #if defined (ACE_PSOS) - // pSOS supports numbers, not names for network interfaces - long net_if, - #else /* ! ACE_PSOS */ - const ASYS_TCHAR *net_if, - #endif /* ! ACE_PSOS */ - </pre><p> - - <li>Protect header files against multiple inclusion with this - construct: - <pre> - #ifndef FOO_H - #define FOO_H - - [contents of header file] - - #endif /* FOO_H */ - </pre><p> - - This exact construct (note the <code>#ifndef</code>) - is optimized by many compilers such they only open the - file once per compilation unit. Thanks to Eric C. Newton - <ecn@smart.net> for pointing that out.<p> - - If the header <code>#includes</code> an ACE library header, - then it's a good idea to include the <code>#pragma once</code> - directive: - <pre> - #ifndef FOO_H - #define FOO_H - - #include "ace/ACE.h" - #if !defined (ACE_LACKS_PRAGMA_ONCE) - # pragma once - #endif /* ACE_LACKS_PRAGMA_ONCE */ - - [contents of header file] - - #endif /* FOO_H */ - </pre><p> - - <code>#pragma once</code> must be protected, because some - compilers complain about it. The protection depends on - <code>ACE_LACKS_PRAGMA_ONCE</code>, which is defined in - some ACE config headers. Therefore, the protected - <code>#pragma once</code> construct should only be used after - an <code>#include</code> of an ACE library header. Note that - many compilers enable the optimization if the <code>#ifndef</code> - protection construct is used, so for them, <code>#pragma once</code> - is superfluous.<p> - - <strong>No</strong> code can appear after the final - <code>#endif</code> for the optimization to be effective and - correct.<p> - </ul> - - <li><strong>C++ Syntax and Constructs</strong><p> - <ul> - <li><strong><code>for</code></strong> loops should look like: - <pre> - for (size_t i = 0; i < Options::instance ()->spawn_count (); ++i) - spawn (); - </pre> - Though, I prefer to always wrap the body of the loop in braces, - to avoid surprises when other code or debugging statements are - added, and to maintain sanity when the body consists of a macro, - such as an ACE_ASSERT without a trailing semicolon: - <pre> - for (size_t i = 0; i < Options::instance ()->spawn_count (); ++i) - { - ACE_ASSERT (spawn () == 0;) - } - </pre><p> - - Similarly, <strong><code>if</code></strong> statements should have - a space after the ``<strong>if</strong>'', and no spaces just after - the opening parenthesis and just before the closing parenthesis.<p> - - <li>If a loop index is used after the body of the loop, it - <strong>must</strong> be declared before the loop. For example, - - <pre> - size_t i = 0; - for (size_t j = 0; file_name [j] != '\0'; ++i, ++j) - { - if (file_name [j] == '\\' && file_name [j + 1] == '\\') - ++j; - - file_name [i] = file_name [j]; - } - - // Terminate this string. - file_name [i] = '\0'; - </pre><p> - - <li>Prefix operators are sometimes more efficient than postfix - operators. Therefore, they are preferred over their postfix - counterparts where the expression value is not used.<p> - - Therefore, use this idiom for iterators, with prefix operator - on the loop index: - <pre> - ACE_Ordered_MultiSet<int> set; - ACE_Ordered_MultiSet_Iterator<int> iter(set); - - for (i = -10; i < 10; ++i) - set.insert (2 * i + 1); - - </pre> - rather than the postfix operator: - <pre> - for (i = -10; i < 10; i++) - set.insert (2 * i + 1); - </pre><p> - - <li>Avoid unnecessary parenthesis. We're not writing Lisp :-)<p> - - <li>Put inline member functions in a <strong><code>.i</code></strong> - file. That file is conditionally included by both the - <strong><code>.h</code></strong> file, for example:<p> - - <pre> - class ACE_Export ACE_High_Res_Timer - { - [...] - }; - - #if defined (__ACE_INLINE__) - #include "ace/High_Res_Timer.i" - #endif /* __ACE_INLINE__ */ - </pre><p> - - and <strong><code>.cpp</code></strong> file:<p> - - <pre> - #define ACE_BUILD_DLL - #include "ace/High_Res_Timer.h" - - #if !defined (__ACE_INLINE__) - #include "ace/High_Res_Timer.i" - #endif /* __ACE_INLINE__ */ - - ACE_ALLOC_HOOK_DEFINE(ACE_High_Res_Timer) - </pre><p> - - <strong>NOTE:</strong> It is very important to ensure than an - inline function will not be used before its definition is seen. - Therefore, the inline functions in the .i file should be arranged - properly. Some compilers, such as <code>g++</code> with the - <code>-Wall</code> option, will issue warnings for violations.<p> - - <li><code>ACE_Export</code> must be inserted between the - <code>class</code> keyword and class name for all classes that - are exported from libraries, as shown in the example above. - <strong>However</strong>, do <strong>not</strong> use - <code>ACE_Export</code> for template classes!<p> - - <li>Mutators and accessors should be of this form:<p> - - <pre> - void object_addr (const ACE_INET_Addr &); - // Sets <object_addr_> cache from <host> and <port>. - - ACE_INET_Addr &object_addr (void); - // Returns the <ACE_INET_Addr> for this profile. - </pre><p> - - instead of the ``set_'' and ``get_'' form.<p> - - <li>Never use <strong><code>delete</code></strong> to deallocate - memory that was allocated with <strong><code>malloc</code></strong>. - Similarly, never associate <strong><code>free</code></strong> with - <strong><code>new</code></strong>. - <strong><code>ACE_NEW</code></strong> or - <strong><code>ACE_NEW_RETURN</code></strong> should be used to - allocate memory, and <strong><code>delete</code></strong> should - be used to deallocate it. And be careful to use the correct form, - <strong><code>delete</code></strong> or - <strong><code>delete []</code></strong> to correspond to the - allocation.<p> - - <li>Don't check for a pointer being 0 before deleting it. It's - always safe to delete a 0 pointer. If the pointer is visible - outside the local scope, it's often a good idea to 0 it - _after_ deleting it. Note, the same argument applies to - free().<p> - - <li>Always use <strong><code>ACE_NEW</code></strong> or - <strong><code>ACE_NEW_RETURN</code></strong> to allocate memory, - because they check for successful allocation and set errno - appropriately if it fails.<p> - - <li>Never compare or assign a pointer value with <strong>NULL</strong>; - use <strong>0</strong> instead. The language allows any pointer to - be compared or assigned with <strong>0</strong>. The definition - of <strong>NULL</strong> is implementation dependent, so it is - difficult to use portably without casting.<p> - - <li>Never cast a pointer to or from an <strong><code>int</code></strong>. - On all currently supported ACE platforms, it is safe to cast - a pointer to or from a <strong><code>long</code></strong>.<p> - - <li>Be very careful when selecting an integer type that must be a - certain size, <em>e.g.</em>, 4 bytes. <strong>long</strong> is - not 4 bytes on all platforms; it is 8 bytes on many 64-bit - machines. ACE_UINT32 is always 4 bytes, and ACE_UINT64 is - always 8 bytes.<p> - - <li>If a class has any virtual functions, and its destructor is - declared explicitly in the class, then the destructor should - <strong>always</strong> be virtual as well. And to support - compiler activities such as generation of virtual tables and, - in some cases, template instantiation, the virtual destructor - should <strong>not be inline</strong>. (Actually, any non-pure - virtual function could be made non-inline for this purpose. But, - for convenience, if its performance is not critical, it is usually - easiest just to make the virtual destructor non-inline.)<p> - - <li>Constructor initializers must appear in the same order as - the data members are declared in the class header. This avoids - subtle errors, because initialization takes place in the order - of member declaration.<p> - - <li>Initialization is usually cleaner than assignment, especially - in a conditional. So, instead of writing code like this: - - <pre> - ssize_t n_bytes; - - // Send multicast of one byte, enough to wake up server. - if ((n_bytes = multicast.send ((char *) &reply_port, - sizeof reply_port)) == -1) - </pre> - - Write it like this: - - <pre> - ssize_t n_bytes = multicast.send ((char *) &reply_port, - sizeof reply_port) - - // Send multicast of one byte, enough to wake up server. - if (n_bytes == -1) - </pre><p> - - But, beware if the initialization is of a static variable. - A static variable is only initialized the first time its - declaration is seen. Of course, we should avoid using - static variables at all.<p> - - <li>It is usually clearer to write conditionals that have - both branches without a negated condition. For example,<p> - - <pre> - if (test) - { - // true branch - } - else - { - // false branch - } - </pre><p> - - is preferred over:<p> - - <pre> - if (! test) - { - // false test branch - } - else - { - // true test branch - } - </pre><p> - - <li>If a cast is necessary, avoid use of function-style casts, - <em>e.g.</em>, <code>int (foo)</code>. Instead, use - one of the ACE cast macros: - - <pre> - return ACE_static_cast(size_t, this->count_) > that->size_; - </pre><p> - - The general usage guidelines for the four styles of casts are:<p> - <ul> - <li><strong>ACE_const_cast</strong>: use to cast away - constness, or volatile-ness.<p> - <li><strong>ACE_static_cast</strong>: use to cast between - compatible types, such as downcasting a pointer or narrowing - an integer.<p> - <li><strong>ACE_reinterpret_cast</strong>: use only when - ACE_static_cast is not suitable.<p> - <li><strong>ACE_dynamic_cast</strong>: avoid, unless you really - want to type check at run-time.<p> - </ul> - - <li>In general, if instances of a class should not be copied, - then a private copy constructor and assignment operator should - be declared for the class, but not implemented. For example: - - <pre> - // Disallow copying by not implementing the following . . . - ACE_Object_Manager (const ACE_Object_Manager &); - ACE_Object_Manager &operator= (const ACE_Object_Manager &); - </pre><p> - - If the class is a template class, then the - <code>ACE_UNIMPLEMENTED_FUNC</code> macro should be used: - - <pre> - // = Disallow copying... - ACE_UNIMPLEMENTED_FUNC (ACE_TSS (const ACE_TSS<TYPE> &)) - ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS<TYPE> &)) - </pre><p> - - <code>ACE_UNIMPLEMENTED_FUNC</code> can be used with non-template - classes as well. Though for consistency and maximum safety, it - should be avoided for non-template classes.<p> - - <li>Never use <code>bool</code>, <code>BOOL</code>, or similar - types. (CORBA::Boolean is acceptable). Use <code>int</code> - or <code>u_int</code> instead for boolean types.<p> - - <li>Functions should always return -1 to indicate failure, and - 0 or greater to indicate success.<p> - </ul> - - <li><strong>I/O</strong><p> - <ul> - <li>Use <strong><code>ACE_DEBUG</code></strong> for printouts, - and <strong><code>ACE_OS::scanf/fprintf ()</code></strong> for - file I/O. Avoid using iostreams because of implementation - differences across platforms.<p> - <li>After attempting to open an existing file, always check for success. - Take appropriate action if the open failed.<p> - </ul> - - <li><strong>UNICODE conformity</strong><p> - - <ul> - <li>Define strings as <strong><code>ASYS_TCHAR</code></strong> if - they need to be passed into system API. It expands to - <code>wchar_t</code> only when - <code>ACE_HAS_MOSTLY_UNICODE_APIS</code> is defined.<p> - - <li>Use <strong><code>ASYS_TEXT</code></strong> and - <strong><code>ASYS_WIDE_STRING</code></strong> for format - strings and other string arguments passed to - <code>ACE_DEBUG</code> or <code>ACE_ERROR</code>. For - example,<p> - <pre> - void - ACE_FOO::ace_bar (int err, ASYS_TCHAR *astr) - { - ACE_TRACE ("ACE_FOO::ace_bar"); - - ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("From ACE_FOO::ace_bar"))); - - if (err) - ACE_ERROR ((LM_ERROR, - ASYS_TEXT ("(%P) Printing this string %s\n"), - astr)); - } - </pre> - <p> - This is because ACE also support platforms which use UNICODE - in most of their APIs. On these platforms, ACE also uses - UNICODE as its system string type.<p> - - <li><strong><code>ACE_TRACE</code></strong> handles conversion - between char strings and UNICODE strings automatically.<p> - - <li>Other helper macros include - <strong><code>ASYS_MULTIBYTE_STRING</code></strong> and - <strong><code>ASYS_ONLY_MULTIBYTE_STRING</code></strong>. See - the end of <a href="../ace/OS.h">OS.h</a> for more details.<p> - - </ul><p> - - <li><strong>Exceptions</strong><p> - - <ul> - <li>There are many ways of throwing and catching exceptions. The - code below gives several examples. Note that each method has - different semantics and costs. Whenever possible, use the - first approach.<p> - - <pre> - #include "iostream.h" - - class exe_foo - { - public: - exe_foo (int data) : data_ (data) - { cerr << "constructor of exception called" << endl; } - ~exe_foo () - { cerr << "destructor of exception called" << endl; } - exe_foo (const exe_foo& foo) : data_ (foo.data_) - { cerr << "copy constructor of exception called" << endl; } - int data_; - }; - - - void - good (int a) - { - throw exe_foo (a); - }; - - void - bad (int a) - { - exe_foo foo (a); - throw foo; - }; - - int main () - { - cout << endl << "First exception" << endl << endl; - try - { - good (0); - } - catch (exe_foo &foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - cout << endl << "Second exception" << endl << endl; - try - { - good (0); - } - catch (exe_foo foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - cout << endl << "Third exception" << endl << endl; - try - { - bad (1); - } - catch (exe_foo &foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - cout << endl << "Fourth exception" << endl << endl; - try - { - bad (1); - } - catch (exe_foo foo) - { - cerr << "exception caught: " << foo.data_ << endl; - } - - return 0; - } - </pre> - - Output is: <p> - - <pre> - First exception - - constructor of exception called - exception caught: 0 - destructor of exception called - - Second exception - - constructor of exception called - copy constructor of exception called - exception caught: 0 - destructor of exception called - destructor of exception called - - Third exception - - constructor of exception called - copy constructor of exception called - destructor of exception called - exception caught: 1 - destructor of exception called - - Fourth exception - - constructor of exception called - copy constructor of exception called - destructor of exception called - copy constructor of exception called - exception caught: 1 - destructor of exception called - destructor of exception called - - </pre> - - </ul><p> - -</ul> - - -<hr> -<h3><a href="http://www.cs.wustl.edu/~schmidt/ACE-overview.html">ACE</a> - Usage Guidelines</h3> -<ul> - <li>Always use <strong><code>ACE_OS</code></strong> (static) - member functions instead of bare OS system calls.<p> - - <li>As a general rule, the only functions that should go into the - <strong><code>ACE_OS</code></strong> class are ones that have - direct equivalents on some OS platform. Functions that are - extensions should go in the <strong><code>ACE</code></strong> class.<p> - - <li>Use the <strong><code>ACE_SYNCH_MUTEX</code></strong> macro, - instead of using one of the specific mutexes, such as - <strong><code>ACE_Thread_Mutex</code></strong>. This provides - portability between threaded and non-threaded platforms.<p> - - <li>Avoid creating a static instance of user-defined (class) type. - Instead, either create it as an - <strong><code>ACE_Singleton</code></strong>, - <strong><code>ACE_TSS_Singleton</code></strong>, or as an - <strong><code>ACE_Cleanup</code></strong> object. See the - <strong>ACE</strong> - <a href="../ace/Singleton.h"><code>Singleton.h</code></a>, - <a href="../ace/Object_Manager.h"><code>Object_Manager.h</code></a>, and - <a href="../ace/Managed_Object.h"><code>Managed_Object.h</code></a> - header files for more information.<p> - - Static instances of built-in types, such as - <strong><code>int</code></strong> or any pointer type, are fine.<p> - - Construction of static instance of a user-defined type should - <em>never</em> spawn threads. Because order of construction of - statics across files is not defined by the language, it is usually - assumed that only one thread exists during static construction. - This allows statics suchs as locks to be safely created. We do not - want to violate this assumption.<p> - - <li>Do not use run-time type identification (RTTI). Some platforms - do not support it.<p> - - <li>Do not use exception handling. Some platforms do not support it. - And, it imposes an execution speed penalty.<p> - - <li>Because ACE does not use exception handling, dealing with - failures requires a bit of care. This is especially true - in constructors. Consider the following approach: - - <pre> - ACE_NEW_RETURN (this->name_space_, LOCAL_NAME_SPACE, -1); - - if (ACE_LOG_MSG->op_status () != 0) - .... - </pre> - - This snip of code is from - <a href="../ace/Naming_Context.cpp"><code>ACE_Naming_Context</code></a>. - All failed constructors in ACE (should) call ACE_ERROR. This sets - the thread specific <strong>op_status</strong>, which can be checked - by the caller. This mechanism allows the caller to check for a failed - constructor without the requiring the constructor to throw - exceptions.<p> - - <li>Avoid using the C++ Standard Template Library (STL) in our - applications. Some platforms do not support it yet.<p> - - <li>Be <em>very</em> careful with <code>ACE_ASSERT</code>. It - must only be used to check values; it may never be used to - wrap a function call, or contain any other side effect. That's - because the statement will disappear when ACE_NDEBUG is enabled. - For example, this code is BAD: - <pre> - ACE_ASSERT (this->next (retv) != 0); // BAD CODE! - </pre> - - Instead, the above should be coded this way: - - <pre> - int result = this->next (retv); - ACE_ASSERT (result != 0); - ACE_UNUSED_ARG (result); - </pre><p> - - <li>Never put side effects in <code>ACE_DEBUG</code> code: - <pre> - ACE_DEBUG ((LM_DEBUG, - "handling signal: %d iterations left\n", - --this->iterations_)); // BAD CODE! - </pre> - - Note that this won't work correctly if <code>ACE_NDEBUG</code> is - defined, for the same reason that having side-effects in - <code>ACE_ASSERT</code>s won't work either, <em>i.e.</em>, because - the code is removed.<p> -</ul> - - -<hr> -<h3><a href="http://www.cs.wustl.edu/~schmidt/ACE-overview.html">Other - ACE</a> and - <a href="http://www.cs.wustl.edu/~schmidt/TAO-overview.html">TAO</a> - Guidelines</h3> -<ul> - <li>Never add copyrighted, confidential, or otherwise restricted - code to the ACE or TAO distributions without written permission - from the owner.<p> -</ul> - - -<hr> -<h3><a href="http://www.cs.wustl.edu/~levine/CVS.html">CVS</a> - Usage Guidelines</h3> -<ul> - <li>Always make sure that a change builds and executes correctly - on at least one platform before checking it into the CVS repository.<p> -</ul> - - -<hr> -<h3>Script Guidelines</h3> -<ul> - <li>In general, it's best to write scripts in Perl. It's - OK to use Bourne shell. Never, never, never use csh, ksh, - bash, or any other kind of shell.<p> - - <li>Follow the Perl style guide guide as closely as - possible. <code>man perlstyle</code> to view it. - - <li>Don't specify a hard-coded path to Perl itself. Use - the following code at the top of the script to pick up - perl from the users <code>PATH</code>:<br> - <pre> - eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - </pre><p> - - <li>Never, never, never start the first line of a script - with ``#'', unless the first line is ``#! /bin/sh''. - With just ``#'', t/csh users will spawn a new shell. - That will cause their <code>.[t]cshrc</code> to be - processed, possibly clobbering a necessary part of - their environment.<p> - - <li>If your Perl script relies on features only available - in newer versions of Perl, include the a statement similar - to the following:<br> - <pre> - require 5.003; - </pre> - - <li>Don't depend on <strong><code>.</code></strong> being - in the user's path. If the script spawns another executable - that is supposed to be in the current directory, be sure the - prefix its filename with <strong><code>.</code></strong>.<p> -</ul> - - -<hr> -<h3>Software Engineering Guidelines</h3> -<ul> - <li><strong>Advise</strong>: Keep other developers informed of problems - and progress.<p> - - <li><strong>Authorize</strong>: We have contractual obligations to not - unilaterally change interfaces. If you need to change or remove an - interface, get an OK.<p> - - <li><strong>Minimize</strong> risk: Test all changes. Solicit review of - changes.<p> - - <li><strong>Revise</strong> only when necessary: Every change has risk, - so avoid making any change unless there is a good reason for it.<p> - - <li><strong>Normalize</strong>: Factor out commonality. For example, - maintain a data value in only one place.<p> - - <li><strong>Synthesize</strong>: Build stubs and scaffolding early to - simulate the complete system. Maintain a checked-in version of the - system that cleanly builds and tests at all times.<p> -</ul> - - -<hr> -<h3><a href="http://www.cs.wustl.edu/~schmidt/rules.html">ACE - Design Rules</a></h3> - - -<hr> <P> - <font size=-1> - Last modified <!--#echo var="LAST_MODIFIED" -->.<p> - </font> - -</body> -</html> diff --git a/docs/ACE-inheritance.pdf.gz b/docs/ACE-inheritance.pdf.gz Binary files differdeleted file mode 100644 index e47b122e39d..00000000000 --- a/docs/ACE-inheritance.pdf.gz +++ /dev/null diff --git a/docs/ACE-inheritance.ps.gz b/docs/ACE-inheritance.ps.gz Binary files differdeleted file mode 100644 index 3aa19f4b62f..00000000000 --- a/docs/ACE-inheritance.ps.gz +++ /dev/null diff --git a/docs/ACE-lessons.html b/docs/ACE-lessons.html deleted file mode 100644 index 64c8db551ef..00000000000 --- a/docs/ACE-lessons.html +++ /dev/null @@ -1,267 +0,0 @@ -<HTML> - -<HEAD> -<TITLE>Lessons Learned Building Reusable OO Telecommunication Software</TITLE> -</HEAD> - -<BODY text = "#000000" -link="#000fff" -vlink="#ff0f0f" -bgcolor="#ffffff"> - -<HR> -<H3>Lessons Learned Building Reusable OO Telecommunication Software Frameworks</H3> - -<DT>Douglas C. Schmidt -<DT>Department of Computer Science -<DT>Washington University, St. Louis -<DT><A HREF="http://www.cs.wustl.edu/~schmidt/">http://www.cs.wustl.edu/~schmidt/</A> -<DT><A HREF="mailto:schmidt@cs.wustl.edu">schmidt@cs.wustl.edu</A> - -<P>The following article appeared in the Lucent Bell Labs ``Multiuse -Express'' magazine, Vol. 4, No. 6, December, 1996. <P> - -<P><HR><P> - -<H3>The Distributed Software Crisis</H3> - -Developing complex software systems is expensive and error-prone. -Object-oriented (OO) programming languages [Stroustrup:91,Gosling:96], -components [Box:97], and frameworks [Lewis:95] are heavily touted -technologies for reducing software cost and improving software -quality. When stripped of their hype, the primary benefits of OO stem -from the emphasis on <EM>modularity</EM> and <EM>extensibility</EM>, -which encapsulate volatile implementation details behind stable -interfaces and enhance software reuse. <P> - -Developers in certain well-traveled domains have successfully applied -OO techniques and tools for years. For instance, the Microsoft MFC -GUI framework and OCX components are <EM>de facto</EM> industry -standards for creating graphical business applications on PC -platforms. Although these tools have their limitations, they -demonstrate the productivity benefits of reusing common frameworks and -components.<P> - -Software developers in more complex domains like telecom have -traditionally lacked standard off-the-shelf middleware components. As -a result, telecom developers largely build, validate, and maintain -software systems from scratch. In an era of deregulation and stiff -global competition, this in-house development process is becoming -prohibitively costly and time consuming. Across the industry, this -situation has produced a ``distributed software crisis,'' where -computing hardware and networks get smaller, faster, and cheaper; yet -telecom software gets larger, slower, and more expensive to develop -and maintain. <P> - -The challenges of building distributed software stem from -<EM>inherent</EM> and <EM>accidental</EM> complexities [Brooks:87] -associated with telecom systems: <P> - -<UL> -<LI> Inherent complexity stems from the fundamental challenges of - developing telecom software. Chief among these is detecting and - recovering from network and host failures, minimizing the impact of - communication latency, and determining an optimal partitioning of - service components and workload onto processing elements throughout - a network. <P> - -<LI> Accidental complexity stems from limitations with tools and - techniques used to develop telecom software. A common source of - accidental complexity is the widespread use of algorithmic - decomposition, which results in non-extensible and non-reusable - software designs and implementations. <P> -</UL> - -The lack of extensibility and reuse in-the-large is particularly -problematic for complex distributed telecom software. Extensibility -is essential to ensure timely modification and enhancement of services -and features. Reuse is essential to leverage the domain knowledge of -expert developers to avoid re-developing and re-validating common -solutions to recurring requirements and software challenges. <P> - -While developing high quality reusable software is hard enough, -developing high quality extensible and reusable telecom software is -even harder. Not surprisingly, many companies attempting to build -reusable middleware fail -- often with enormous loss of money, time, -and marketshare. Those companies that do succeed, however, reap the -benefits resulting from their ability to develop and deploy complex -applications rapidly, rather than wrestling endlessly with -infrastructure problems. Unfortunately, the skills required to -successfully produce telecom middleware remain something of a "black -art," often locked in the heads of expert developers. <P> - -<P><HR><P> - -<H3>Lessons Learned Building Reusable OO Communication Software Frameworks</H3> - -Over the past decade, I've worked with many companies (including -Motorola Iridium, Ericsson, Siemens, Bellcore, Kodak, and McDonnell -Douglas) building reusable OO communication software [Schmidt:96]. In -these projects, we've applied a range of OO middleware tools including -OMG <A HREF="corba.html">CORBA</A> (an emerging industry standard for -distributed object computing) and the <A HREF="ACE.html">ACE</A> -framework (a widely used C++ framework that implements many strategic -and tactical design patterns for concurrent communication software). -The following are lessons learned from developing and deploying -reusable OO communication software components and frameworks in -practice: <P> - -<UL> -<LI> <B><EM> Successful reuse-in-the-large requires non-technical -prerequisites -- </EM></B><P> - - Many political, economical, organizational, and psychological - factors can impede successful reuse in telecom companies. I've - found that reuse-in-the-large works best when (1) the marketplace is - competitive (i.e., time-to-market is crucial, so leveraging existing - software substantially reduces development effort), (2) the - application domain is non-trivial (i.e., repeatedly developing - complete solutions from scratch is too costly), and (3) the - corporate culture is supportive of an effective reuse process (e.g., - developers are rewarded for taking the time to build robust reusable - components). When these prerequisites <EM>don't</EM> apply, I've - found that developers often fall victim to the "not-invented-here" - syndrome and rebuild everything from scratch. <P> - -<LI> <B><EM> Iteration and incremental growth is essential </EM></B> -- <P> - - Expanding on the corporate culture theme, I've observed that it's - crucial for software managers to openly support the fact that good - components, frameworks, and software architectures take time to - craft and hone. For reuse to succeed in-the-large, management must - have the vision and resolve to support the incremental evolution of - reusable software. In general, an 80% solution that can be evolved - is often preferable to trying to achieve a 100% solution that never - ships. Fred Brook's observation that ``Plan to throw the first one - away, you will anyway'' [Brooks:75] applies as much today as it did - 20 years ago. <P> - -<LI> <B><EM> Integrate infrastructure developers with application developers -</EM></B> -- <P> - - Truly useful components and frameworks are derived from solving real - problems, e.g., telecommunications, medical imaging, avionics, OLTP, - etc. Therefore, a time honored way of producing reusable components - is to generalize from working systems and applications. In - particular, resist the temptation to create ``component teams'' that - build reusable frameworks in isolation from application teams. I've - learned the hard way that without intimate feedback from application - developers, the software artifacts produced by a component team - won't solve real problems and will not be reused. <P> - -<LI> <B><EM> Industry ``standards'' are not panaceas -- </EM></B> <P> - - Expecting emerging industry standards (like CORBA or TINA) to - eliminate telecom software complexity today is very risky. For - instance, although some CORBA ORB implementations are suited for - certain telecom tasks (such as managing network elements), the - semantics of higher level OMG services (such as the Common Object - Services) are still too vague, under-specified, and non</EM></B> - -interoperable. Although CORBA isn't yet suited to address certain - demanding real-time performance and reliability requirements in the - telecom domain, over the next 2 years we'll see CORBA-based products - emerge that support such features [Schmidt:96].<P> - -<LI> <B><EM> Beware of simple(-minded) solutions to complex software problems --- </EM></B> <P> - - Apply simple solutions to complex problems that sound too good to be - true typically are... For example, translating code entirely from - high-level specifications or using trendy OO design methodologies - and programming languages is no guarantee of success. In my - experience, there's simply no substitute for skilled software - developers, which leads to the following final ``lesson learned.'' -<P> - -<LI> <B><EM> Respect and reward quality developers </EM></B> -- <P> - - Ultimately, reusable components are only as good as the people who - build and use them. Developing robust, efficient, and reusable - telecom middleware requires teams with a wide range of skills. We - need expert analysts and designers who have mastered design - patterns, software architectures, and communication protocols to - alleviate the inherent and accidental complexities of telecom - software. Moreover, we need expert programmers who can implement - these patterns, architectures, and protocols in reusable frameworks - and components. In my experience, it is exceptionally hard to find - high quality software developers. Ironically, many telecom - companies treat their developers as interchangeable, "unskilled - labor" who can be replaced easily. I suspect that over time, - companies who respect and reward their high quality software - developers will increasingly outperform those who don't. <P> -</OL> - -<P><HR><P> -<H3>Concluding Remarks</H3> - -Developing reusable OO middleware components and frameworks is not a -silver bullet. Software is inherently abstract, which makes it hard -to engineer its quality and to manage its production. The good news, -however, is that OO component and framework technologies are becoming -mainstream. Developers and users are increasingly adopting and -succeeding with object-oriented design and programming.<P> - -On the other hand, the bad news is that (1) existing OO components and -frameworks are largely focused on only a few areas (e.g., GUIs) and -(2) existing industry standards still lack the semantics, features, -and interoperability to be truly effective throughout the telecom -software domain. Too often, vendors use industry standards to sell -proprietary software under the guise of open systems. Therefore, it's -essential for telecom companies to work with standards organizations -and middleware vendors to ensure the emerging specifications support -true interoperability and define features that meet telecom software -needs.<P> - -Finally, to support the standardization effort, it's crucial for us to -capture and document the patterns that underlie the successful telecom -software components and frameworks that do exist. Likewise, we need -to reify these patterns to guide the creation of standard frameworks -and components for the telecom domain. I'm optimistic that the next -generation of OO frameworks and components will be a substantial -improvement over those we've worked with in the past.<P> - -For more information on building reusable OO communication software -frameworks with CORBA and ACE, see the following WWW URLs:<P> - -<A HREF="http://www.cs.wustl.edu/~schmidt/corba.html">http://www.cs.wustl.edu/~schmidt/corba.html</A><p> -<A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html">http://www.cs.wustl.edu/~schmidt/ACE.html.</A> - -<P><HR><P> -<H3>References</H3> - -[Box:97] Don Box, "Understanding COM," Addison-Wesley, - Reading, MA, 1997.<P> - -[Brooks:75] Frederick P. Brooks, "The Mythical Man-Month," - Addison-Wesley, Reading, MA, 1975.<P> - -[Brooks:87] Frederick P. Brooks, "No Silver Bullet: Essence and - Accidents of Software Engineering," IEEE Computer, Volume - 20, Number 4, April 1987, 10-19.<P> - -[Gosling:96] The Java Programming Language, Addison-Wesley, - Reading, MA, 1996.<P> - -[Lewis:95], Ted Lewis et al., "Object Oriented Application - Frameworks," IEEE Computer Society Press, 1995.<P> - -[OMG:95] Object Management Group, The Common Object Request Broker: - Architecture and Specification 2.0, July, 1995.<P> - -[Schmidt:96] Douglas C. Schmidt, "A Family of Design Patterns for - Application-Level Gateways," Theory and Practice of Object - Systems, Wiley and Sons, 1996.<P> - -[Schmidt:97] Aniruddha Gokhale, Douglas C. Schmidt, Tim Harrison, and - Guru Parulkar, "Towards Real-time CORBA," IEEE Communications - Magazine, Volume 14, Number 2, February 1997.<P> - -[Stroustrup:91] Bjarne Stroustrup, The C++ Programming Language, 2nd - Edition, Addison-Wesley, Reading, MA, 1991.<P> - -<P><HR><P> -Back to <A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html"> -ACE</A> home page. -<!--#include virtual="/~schmidt/cgi-sig.html" --> -</BODY> -</HTML> diff --git a/docs/ACE-porting.html b/docs/ACE-porting.html deleted file mode 100644 index fcca8011659..00000000000 --- a/docs/ACE-porting.html +++ /dev/null @@ -1,186 +0,0 @@ -<!-- $Id$ --> - -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Generator" CONTENT="Microsoft Word 97"> - <META NAME="Template" CONTENT="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html -.dot"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (Win95; I) [Netscape]"> - <TITLE>Porting ACE and TAO to a New OS Platform</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#FF0000"> - -<HR><P> -<H3>Porting ACE and TAO to a New OS Platform</H3><P> - -The <A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html">ACE</A> -framework and the <A -HREF="http://www.cs.wustl.edu/~schmidt/TAO.html">TAO</A> ORB have been -ported to <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE-versions-i.html">many OS -platforms</A>. Porting ACE and TAO to new platforms is fairly easy. -The following document describes the step-by-step process to use when -porting the various <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE-overview.html">components -and layers</A> in ACE to a new OS platform. Once ACE is ported, it is -straightforward to port TAO, as well.<P> - -<hr align=left width="50%"><P> -<H4>Create a <CODE>config.h</CODE> Header File for the Target OS Platform</H4> - -A <CODE>config-*.h</CODE> header file exists in <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ace/">$ACE_ROOT/ace</A> -for each platform to which ACE has been ported. This file contains -the portability macros for each particular configuration of ACE. A -complete description of the existent macros can be found in the <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ace/README">$ACE_ROOT/ace/README</A> -file. <P> - -Currently, you must edit this file by hand to port it to new OS -platforms. It's a good idea to use the <CODE>config-*.h</CODE> files -for platforms with similar characteristics as examples. Ultimately, -we plan to <A HREF="http://www.cs.wustl.edu/~othman/aceconf">auto -configure</A> these files. <P> - -<hr align=left width="50%"><P> -<H4>Port the <CODE>ACE_OS</CODE> Class</H4> - -The <CODE>ACE_OS</CODE> class encapsulates most of variation between -the different OS implementations, <EM>e.g.</EM>, UNIX, Win32, and -various real-time operating systems. It is the core class of the ACE -OS abstraction layer. Most work required to port ACE to a new OS -platform resides in this class. There are <EM>many</EM> examples of -how ACE has been ported to other operating systems in the -<CODE>ACE_OS</CODE> class in the -<CODE>$ACE_ROOT/ace/OS.{h,i,cpp}</CODE> files. <P> - -Optional features in pthreads are covered by <CODE>ACE_HAS_*</CODE> -and/or <CODE>ACE_LACKS_*</CODE> macros, which are described in the <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ace/README">$ACE_ROOT/ace/README</A> -file. Particular platform features, such as DCE pthreads calls that -end in <CODE>_np</CODE>, should be bracketed by platform defines -rather than by inventing more <CODE>ACE_HAS_*</CODE> or -<CODE>ACE_LACKS_*</CODE> definitions. <P> - -An important part of porting ACE to a new platform is to map the -threading API correctly. Currently, ACE has support for the following -thread APIs: <P> - -<UL> -<LI> <B>UNIX International (UI) Threads</B> - (<CODE>ACE_HAS_STHREADS</CODE>) - Solaris 2, UnixWare. <P> - -<LI> <B>POSIX Pthreads</B> (<CODE>ACE_HAS_PTHREADS</CODE>) - drafts 4 - [DCE], 6 [FSU], 7 [AIX], as well as the final standard (also - called draft 10) [MIT, Linux, and Solaris]. <P> - -<LI> <B>Win32 Threads</B> (<CODE>ACE_HAS_WTHREADS</CODE>) - Windows - NT, Windows '95/98, and Windows CE <P> -<LI> <B>VxWorks Tasks</B> (<CODE>VXWORKS</CODE>) - VxWorks <P> -</UL> - -If your OS platform does not support any of these threading packages, -you must port the <CODE>ACE_OS::thr_*</CODE> functions. <P> - -<hr align=left width="50%"><P> -<H4>Port the C++ Wrapper Components</H4> - -After porting the <CODE>ACE_OS</CODE> class, the next step is to port -all of the ACE C++ wrapper components, such as sockets, threads, -synchronization mechanisms. A full list of the categories and classes -can be found in the <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ACE-categories">$ACE_ROOT/ACE-categories</a> -file. It is easiest to concentrate on porting one category at the -time. The ACE release contain a <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/tests/README">one-button -test suite</A> in the <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/tests/">$ACE_ROOT/tests/</A> -directory. These tests can be used to validate the correctness of the -various ACE C++ wrappers as they are ported. <P> - -<hr align=left width="50%"><P> -<H4>Port the Higher-level Framework Components of ACE</H4> - -Having ported (and tested) all the components of the ACE OS adaptation -layer and C++ wrappers, you can proceed to port the higher level -components of ACE, such as the Reactor, Service Configurator, -Connector, Acceptor, and Streams frameworks. At this point, it should -be relatively easy to port the rest of ACE because most of the -platform-dependent code is localized in the lower layers of ACE. <P> - -<hr align=left width="50%"><P> -<H4>Port TAO</H4> - -After porting and successfully testing all the ACE framework -components, it also should be relatively easy to port and <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/TAO/TAO-INSTALL.html">install</A> -TAO because all of its platform-dependent code is localized in ACE. -Typically, the only problems that arise when porting TAO is bugs with -C++ compilers. <P> - -<HR><P> -<H3>C++ Features Required to Port ACE and TAO</H3> - -ACE and TAO have been ported to most C++ compilers. The following is -a list of which C++ features a compiler must support in order to -compile ACE and TAO: - -<UL> -<LI> <B>Templates</B> -- The C++ compiler must support templates. - However, it need not support template member functions nor must it - support template traits. <P> - -<LI> <B>Multiple inheritance and dynamic binding</B> -- The C++ - compiler must support multiple inheritance and dynamic - binding. <P> -</UL> - -The following is a list of which C++ features that ACE and TAO can -take advantage of if a compiler supports them: - -<UL> -<LI> <B>Exceptions</B> -- The ACE library itself is ``exception - neutral,'' <EM>i.e.,</EM> it does not catch or throw C++ - exceptions. However, you can use exceptions in code - that uses ACE including throwing exceptions inside call back - methods, as long as you provide the code to handle it. - TAO can be configured to use C++ exceptions if ACE supports them, - <EM>i.e.</EM>, if <CODE>ACE_HAS_EXCEPTIONS</CODE> is defined. <P> - -<LI> <B>RTTI and ANSI casts</B> -- If the OS platform supports RTTI - and the new ANSI - C++ casts, <EM>i.e.</EM>, <CODE>ACE_HAS_ANSI_CASTS</CODE> is - enabled, then the various <CODE>ACE_*_cast</CODE> macros will - utilize these casts. Otherwise, the macros will default to - "C-style" casts. <P> - -<LI> <B>Namespaces</B> -- ACE does not utilize namespaces. However, - TAO will automatically take advantage of namespaces if the C++ - compiler supports them, <EM>i.e.</EM>, if - <CODE>ACE_HAS_BROKEN_NAMESPACES</CODE> is <EM>not</EM> enabled. <P> - -<LI> <B>STL</B> -- Unfortunately many of the platforms that ACE - supports don't have an STL library. Moreover, different versions - of STL behave differently. Therefore, ACE does not depends on - STL and does not use it internally. - If your target platform(s) support STL you should be able to - use it with ACE and TAO without problems, though your C++ - compiler may have problems with it (this is beyond the scope - of ACE, however). <P> - - If you are considering STL, you might consider - <A HREF="http://corp.metabyte.com/~fbp/stl/index.html">STLport</a>, - which is a port of the SGI STL to numerous platforms that ACE - and TAO also support. <P> -</UL> - -<P><HR><P> - -Back to the <A -HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ACE-documentation.html">ACE -documentation</A> page. - -<!--#include virtual="/~schmidt/cgi-sig.html" --> -</BODY> -</HTML> diff --git a/docs/ACE-subsets.html b/docs/ACE-subsets.html deleted file mode 100644 index 8edca93105b..00000000000 --- a/docs/ACE-subsets.html +++ /dev/null @@ -1,695 +0,0 @@ -<HTML> - -<HEAD> -<TITLE>ACE Subsets</TITLE> - -<BODY text = "#000000" -link="#000fff" -vlink="#ff0f0f" -bgcolor="#ffffff"> - -<HR> -<H3>Proposal for Splitting ACE into Multiple Libraries</H3> - -The following is a draft of our proposal for spliting ACE into -multiple libraries, each of which will contain a smaller subset of the -overall ACE functionality. The primary motivations for subsetting ACE -are: - -<UL> -<LI> <EM>Principle of parsimony</EM> -- <EM>i.e.</EM>, developers - should incur time/space overhead for components they use, rather - than for all the components in the ACE framework. <P> - -<LI> <EM>Simplify the learning curve</EM> -- <EM>i.e.</EM>, developers - only need to learn how to program components that they actually - use. <P> -</UL> - -The main design goals of this proposal are as follows: <P> - -<OL> -<LI> Support the original libACE as before. Thus, for users who -want to use the existing ACE library as is, there will be -no changes, i.e., just link with <CODE>libACE</CODE> as usual. <P> - -<LI> Allow ACE (and TAO) programmers to use smaller subsets of the -entire <CODE>libACE</CODE> library. These subsets will include the -following libraries: <P> - -<DL> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_OS</CODE> -- This library contains the OS adaptation -layer and its supporting classes. All other ACE libraries will depend -on <CODE>libACE_OS</CODE> and it will depend on <EM>no</EM> other ACE -libraries. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Utils</CODE> -- This library contains the various ACE -container classes and other miscellaneous classes, such as Singleton, -auto_ptr, timers, etc. This library will depend only on -<CODE>libACE_OS</CODE>.<P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Logging</CODE> -- This library contains the various ACE -logging and tracing classes. This library will depend only on -<CODE>libACE_OS</CODE>. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Threads</CODE> -- This library contains the ACE -thread/process management and synchronization classes. This library -will depend only on <CODE>libACE_OS</CODE>. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Demux</CODE> -- This library contains the ACE Reactor and -Proactor classes. This library will depend on <CODE>libACE_OS</CODE> -and <CODE>libACE_Thread</CODE>. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Connection</CODE> -- This library contains the ACE -Connection components, i.e., Acceptor, Connector, and Svc_Handler. -This library will depend on <CODE>libACE_OS</CODE>, -<CODE>libACE_Thread</CODE>, and <CODE>libACE_Demux</CODE>. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Sockets</CODE> -- This library contains the ACE C++ -wrappers for sockets. This library will depend on -<CODE>libACE_OS</CODE>. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_IPC</CODE> -- This library contains all the ACE C++ -wrappers for the other types of IPC and FILE I/O other than sockets. -This library will depend on <CODE>libACE_OS</CODE> and -<CODE>libACE_Sockets</CODE>. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Svcconf</CODE> -- This library contains the ACE C++ -wrappers for the Service Configurator. This library will depend on -<CODE>libACE_OS</CODE>, <CODE>libACE_Demux</CODE>, -<CODE>libACE_Thread</CODE>, and <CODE>libACE_Sockets</CODE>. <P> - -<DT> <img alt="o" src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Streams</CODE> -- This library contains the ACE Streams -classes. This library will depend on <CODE>libACE_OS</CODE>, -<CODE>libACE_Demux</CODE>, and <CODE>libACE_Thread</CODE>. <P> - -<DT> <img alt="o" -src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> -<CODE>libACE_Memory</CODE> -- This library contains the ACE C++ -wrappers for shared memory and memory-mapped files. This library will -depend on <CODE>libACE_OS</CODE>.<P> - -</DL> -</OL> - -In addition, we will create <CODE>libACE_TAO</CODE>, which contains -just the core set of components in ACE that are required to support -TAO. This library is targeted at embedded systems developers who want -to minimize the footprint of ACE+TAO. <P> - -Note that the ACE library subsets described above are intended as a -guideline, <EM>not</EM> a complete specification. The actual -partitioning of files in the final ACE library subsets may differ -somewhat in order to improve footprint and simplify common -use-cases. <P> - -<HR><P> -<H3>Configuration Management</H3> - -Configuration management for the ACE library subsets described above -will be organized as follows: - -<OL> -<LI> A single source tree with a single "version" for the source - tree. <P> - -<LI> Releases of libACE and its "subsets" will be atomic, <EM>i.e.</EM>, - all or nothing. <P> -</OL> - -<HR><P> -<H3>Classes in Each ACE Library Subset</H3> - -Below, we describe the classes in each ACE library subset. - -<H4>libACE_OS</H4> - -This library contains the OS adaptation layer and its supporting -classes. The classes in this library should not depend on any other -ACE library subsets. All of the other libraries will depend on this -library. The following classes are included in this library. - -<PRE><CODE> -ACE.cpp -ACE.h -ACE.i -config.h -Basic_Types.cpp -Basic_Types.h -Basic_Types.i -OS.cpp -OS.h -OS.i -Version.h -</PRE></CODE> - -<H4>libACE_Utils</H4> - -This library contains the following ACE container classes and other -miscellaneous classes. - -<PRE><CODE> -ARGV.cpp -ARGV.h -ARGV.i -Array.cpp -Array.h -Array.i -Auto_Ptr.cpp -Auto_Ptr.h -Auto_Ptr.i -Containers.cpp -Containers.i -Containers.h -Date_Time.cpp -Date_Time.h -Date_Time.i -Dynamic.cpp -Dynamic.h -Dynamic.i -Filecache.cpp -Filecache.h -Free_List.cpp -Free_List.i -Free_List.h -Get_Opt.cpp -Get_Opt.h -Get_Opt.i -Hash_Map_Manager.cpp -Hash_Map_Manager.h -High_Res_Timer.cpp -High_Res_Timer.h -High_Res_Timer.i -Managed_Object.cpp -Managed_Object.h -Managed_Object.i -Map_Manager.cpp -Map_Manager.h -Map_Manager.i -Object_Manager.cpp -Object_Manager.i -Object_Manager.h -Profile_Timer.cpp -Profile_Timer.h -Profile_Timer.i -Registry.cpp -Registry.h -Singleton.cpp -Singleton.h -Singleton.i -SString.cpp -SString.h -SString.i -System_Time.cpp -System_Time.h -Time_Request_Reply.cpp -Time_Request_Reply.h -Time_Value.cpp -Time_Value.h -Time_Value.i -Timer_Hash.cpp -Timer_Hash.h -Timer_Hash_T.cpp -Timer_Hash_T.h -Timer_Heap.cpp -Timer_Heap.h -Timer_Heap.i -Timer_Heap_T.cpp -Timer_Heap_T.h -Timer_Heap_T.i -Timer_List.cpp -Timer_List.h -Timer_List.i -Timer_List_T.cpp -Timer_List_T.h -Timer_List_T.i -Timer_Queue.cpp -Timer_Queue.h -Timer_Queue.i -Timer_Queue_Adapters.cpp -Timer_Queue_Adapters.h -Timer_Queue_Adapters.i -Timer_Queue_T.cpp -Timer_Queue_T.h -Timer_Queue_T.i -Timer_Wheel.cpp -Timer_Wheel.h -Timer_Wheel.i -Timer_Wheel_T.cpp -Timer_Wheel_T.h -Timer_Wheel_T.i -</PRE></CODE> - -<H4>libACE_Logging</H4> - -This library contains the various ACE logging and tracing classes. - -<PRE><CODE> -Dump.cpp -Dump.h -Dump_T.cpp -Dump_T.h -Log_Msg.cpp -Log_Msg.h -Log_Msg.i -Log_Priority.h -Log_Record.cpp -Log_Record.h -Log_Record.i -Trace.cpp -Trace.h -Trace.i -</PRE></CODE> - -<H4>libACE_Threads</H4> - -This library contains the ACE thread/process management and -synchronization classes. - -<PRE><CODE> -Activation_Queue.h -Activation_Queue.cpp -Atomic_Op.i -Future.h -Future.cpp -Method_Object.h -Method_Object.cpp -Process.cpp -Process.h -Process.i -Process_Manager.cpp -Process_Manager.h -Process_Manager.i -Sched_Params.cpp -Sched_Params.h -Sched_Params.i -Synch.cpp -Synch.h -Synch.i -Synch_Options.cpp -Synch_Options.h -Synch_Options.i -Synch_T.cpp -Synch_T.h -Synch_T.i -Thread.cpp -Thread.h -Thread.i -Thread_Manager.cpp -Thread_Manager.h -Thread_Manager.i -Token.cpp -Token.h -Token.i -</PRE></CODE> - -<H4>libACE_Demux</H4> - -This library contains the ACE Reactor and its associated classes, -including the ACE Connection components. - -<PRE><CODE> -Event_Handler.cpp -Event_Handler.h -Event_Handler.i -Event_Handler_T.cpp -Event_Handler_T.h -Event_Handler_T.i -Handle_Set.cpp -Handle_Set.h -Handle_Set.i -Priority_Reactor.cpp -Priority_Reactor.i -Priority_Reactor.h -Proactor.h -Proactor.i -Proactor.cpp -Reactor.cpp -Reactor.h -Reactor.i -Reactor_Impl.h -Select_Reactor.cpp -Select_Reactor.h -Select_Reactor.i -WFMO_Reactor.cpp -WFMO_Reactor.h -WFMO_Reactor.i -XtReactor.cpp -XtReactor.h -</PRE></CODE> - -<H4>libACE_Connection</H4> - -This library contains the ACE Connection components, i.e., Acceptor, -Connector, and Svc_Handler. - -<PRE><CODE> -Acceptor.cpp -Acceptor.h -Acceptor.i -Asynch_Acceptor.cpp -Asynch_Acceptor.h -Asynch_Acceptor.i -Asynch_IO.cpp -Asynch_IO.h -Asynch_IO.i -Connector.cpp -Connector.h -Connector.i -Dynamic_Service.cpp -Dynamic_Service.h -Dynamic_Service.i -Strategies.cpp -Strategies.h -Strategies.i -Strategies_T.cpp -Strategies_T.h -Strategies_T.i -Svc_Handler.cpp -Svc_Handler.h -Svc_Handler.i -</PRE></CODE> - -<H4>libACE_Sockets</H4> - -This library contains the ACE C++ wrappers for sockets. - -<PRE><CODE> -IPC_SAP.cpp -IPC_SAP.h -IPC_SAP.i -LOCK_SOCK_Acceptor.cpp -LOCK_SOCK_Acceptor.h -LSOCK.cpp -LSOCK.h -LSOCK.i -LSOCK_Acceptor.cpp -LSOCK_Acceptor.h -LSOCK_Acceptor.i -LSOCK_CODgram.cpp -LSOCK_CODgram.h -LSOCK_CODgram.i -LSOCK_Connector.cpp -LSOCK_Connector.h -LSOCK_Connector.i -LSOCK_Dgram.cpp -LSOCK_Dgram.h -LSOCK_Dgram.i -LSOCK_Stream.cpp -LSOCK_Stream.h -LSOCK_Stream.i -SOCK.cpp -SOCK.h -SOCK.i -SOCK_Acceptor.cpp -SOCK_Acceptor.h -SOCK_Acceptor.i -SOCK_CODgram.cpp -SOCK_CODgram.h -SOCK_CODgram.i -SOCK_Connector.cpp -SOCK_Connector.h -SOCK_Connector.i -SOCK_Dgram.cpp -SOCK_Dgram.h -SOCK_Dgram.i -SOCK_Dgram_Bcast.cpp -SOCK_Dgram_Bcast.h -SOCK_Dgram_Bcast.i -SOCK_Dgram_Mcast.cpp -SOCK_Dgram_Mcast.h -SOCK_Dgram_Mcast.i -SOCK_IO.cpp -SOCK_IO.h -SOCK_IO.i -SOCK_Stream.cpp -SOCK_Stream.h -SOCK_Stream.i - -</PRE></CODE> - -<H4>libACE_IPC</H4> - -This library contains all the ACE C++ wrappers for the other types of -IPC and FILE I/O other than sockets. This library will depend on the -<CODE>libACE_Socket</CODE> library. - -<PRE><CODE> - -Addr.cpp -Addr.h -Addr.i -DEV.cpp -DEV.h -DEV.i -DEV_Addr.cpp -DEV_Addr.h -DEV_Addr.i -DEV_Connector.cpp -DEV_Connector.h -DEV_Connector.i -DEV_IO.cpp -DEV_IO.h -DEV_IO.i -FIFO.cpp -FIFO.h -FIFO.i -FIFO_Recv.cpp -FIFO_Recv.h -FIFO_Recv.i -FIFO_Recv_Msg.cpp -FIFO_Recv_Msg.h -FIFO_Recv_Msg.i -FIFO_Send.cpp -FIFO_Send.h -FIFO_Send.i -FIFO_Send_Msg.cpp -FIFO_Send_Msg.h -FIFO_Send_Msg.i -FILE_Addr.cpp -FILE_Addr.h -FILE_Addr.i -FILE.cpp -FILE.h -FILE.i -FILE_Connector.cpp -FILE_Connector.h -FILE_Connector.i -FILE_IO.cpp -FILE_IO.h -FILE_IO.i -INET_Addr.cpp -INET_Addr.h -INET_Addr.i -IO_SAP.cpp -IO_SAP.h -IO_SAP.i -IOStream.cpp -IOStream.h -IOStream_T.cpp -IOStream_T.h -IOStream_T.i -Pipe.cpp -Pipe.h -Pipe.i -Signal.cpp -Signal.h -Signal.i - -SPIPE_Addr.cpp -SPIPE_Addr.h -SPIPE_Addr.i -SPIPE.cpp -SPIPE.h -SPIPE.i -SPIPE_Acceptor.cpp -SPIPE_Acceptor.h -SPIPE_Acceptor.i -SPIPE_Connector.cpp -SPIPE_Connector.h -SPIPE_Connector.i -SPIPE_Stream.cpp -SPIPE_Stream.h -SPIPE_Stream.i -SV_Message.cpp -SV_Message.h -SV_Message.i -SV_Message_Queue.cpp -SV_Message_Queue.h -SV_Message_Queue.i -SV_Semaphore_Complex.cpp -SV_Semaphore_Complex.h -SV_Semaphore_Complex.i -SV_Semaphore_Simple.cpp -SV_Semaphore_Simple.h -SV_Semaphore_Simple.i -SV_Shared_Memory.cpp -SV_Shared_Memory.h -SV_Shared_Memory.i -TLI.cpp -TLI.h -TLI.i -TLI_Acceptor.cpp -TLI_Acceptor.h -TLI_Acceptor.i -TLI_Connector.cpp -TLI_Connector.h -TLI_Connector.i -TLI_Stream.cpp -TLI_Stream.h -TLI_Stream.i -TTY_IO.cpp -TTY_IO.h -Typed_SV_Message.cpp -Typed_SV_Message.h -Typed_SV_Message.i -Typed_SV_Message_Queue.cpp -Typed_SV_Message_Queue.h -Typed_SV_Message_Queue.i -UNIX_Addr.cpp -UNIX_Addr.h -UNIX_Addr.i -UPIPE_Addr.h -UPIPE_Acceptor.cpp -UPIPE_Acceptor.h -UPIPE_Acceptor.i -UPIPE_Connector.cpp -UPIPE_Connector.h -UPIPE_Connector.i -UPIPE_Stream.cpp -UPIPE_Stream.h -UPIPE_Stream.i -</PRE></CODE> - -<H4>libACE_Svcconf</H4> - -This library contains the ACE C++ wrappers for the Service -Configurator component. - -<PRE><CODE> -Parse_Node.cpp -Parse_Node.h -Parse_Node.i -Service_Config.cpp -Service_Config.h -Service_Config.i -Service_Main.cpp -Service_Manager.cpp -Service_Manager.h -Service_Manager.i -Service_Object.cpp -Service_Object.h -Service_Object.i -Service_Record.cpp -Service_Record.h -Service_Record.i -Service_Repository.cpp -Service_Repository.h -Service_Repository.i -Service_Types.cpp -Service_Types.i -Service_Types.h -Shared_Object.cpp -Shared_Object.h -Shared_Object.i -Svc_Conf.h -Svc_Conf_l.cpp -Svc_Conf_y.cpp -Svc_Conf_Tokens.h -</PRE></CODE> - -<H4>libACE_Streams</H4> - -This library contains the ACE Streams classes. - -<PRE><CODE> -IO_Cntl_Msg.cpp -IO_Cntl_Msg.h -IO_Cntl_Msg.i -Message_Block.cpp -Message_Block.h -Message_Block.i -Message_Queue.cpp -Message_Queue.h -Message_Queue.i -Message_Queue_T.cpp -Message_Queue_T.h -Message_Queue_T.i -Module.cpp -Module.h -Module.i -Multiplexor.cpp -Multiplexor.h -Multiplexor.i -Stream.cpp -Stream.h -Stream.i -Stream_Modules.cpp -Stream_Modules.h -Stream_Modules.i -Task.cpp -Task.h -Task.i -Task_T.cpp -Task_T.h -Task_T.i -</PRE></CODE> - -<H4>libACE_Memory</H4> - -This library contains the ACE C++ wrappers for shared memory and -memory-mapped files. - -<PRE><CODE> -Malloc.cpp -Malloc.h -Malloc.i -Malloc_T.cpp -Malloc_T.h -Malloc_T.i -Mem_Map.cpp -Mem_Map.h -Mem_Map.i -Memory_Pool.cpp -Memory_Pool.h -Memory_Pool.i -Obstack.cpp -Obstack.h -Read_Buffer.cpp -Read_Buffer.h -Read_Buffer.i -Shared_Memory.h -Shared_Memory_MM.cpp -Shared_Memory_MM.h -Shared_Memory_MM.i -Shared_Memory_SV.cpp -Shared_Memory_SV.h -Shared_Memory_SV.i -</PRE></CODE> - -<HR><P> -Back to the <A HREF="ACE.html">ACE</A> home page. - -<!--#include virtual="/~schmidt/cgi-sig.html" --> -</BODY> -</HTML> diff --git a/docs/ACE-tutorials.html b/docs/ACE-tutorials.html deleted file mode 100644 index 5e260b5711a..00000000000 --- a/docs/ACE-tutorials.html +++ /dev/null @@ -1,56 +0,0 @@ -<HTML> - <TITLE>ACE Beginners' Guide</TITLE> - <BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - <HR><P> - <H3>The Beginners' Guide to ACE</H3> - - The <A HREF="http://www.cs.wustl.edu/~schmidt/ACE-members.html">ACE - development team</A> is creating a set of tutorials to help ACE - newcomers learn how to use the framework effectively. The following - links provide further information on this topic. <P> - - <TABLE cellpadding=10 cellspacing=0 border=0> - <TD> - <DL> - <DT> <img alt="o" src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> <A - HREF="http://www.cs.wustl.edu/~schmidt/ACE-overview.html">Overview of ACE</A> - - <DT> <img alt="o" - src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> - ACE programmers guide <A HREF="http://www.cs.wustl.edu/~schmidt/PDF/ACE-tutorial.pdf.gz">[pdf]</A><A HREF="http://www.cs.wustl.edu/~schmidt/ACE-tutorial.ps.gz">[ps]</A> - - <DT> <img alt="o" src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> - <A - HREF="tutorials/guide-tutorials.html">Online examples from the ACE programmers guide</A> - - <DT> <img alt="o" src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> - <A - HREF="tutorials/online-tutorials.html">Introductory online ACE tutorials</A> - - <DT> <img alt="o" src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> - <A HREF="tutorials/new-tutorials.html">Developing new tutorials</A> - - <!-- Bob's original can always be found at: http://dox.netwrench.com/acedox/fmm/ --> - <DT> <img alt="o" src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> - <A - HREF="http://www.cs.wustl.edu/~schmidt/ACE_wrappers/ACE-papers.html">ACE technical papers</A> - <DT> <img alt="o" src="http://www.cs.wustl.edu/~schmidt/gifs/misc/redball.gif"> - <A - HREF="ACE-FMM.html">ACE -``frequently made mistakes'' (FMM)</A> - - </DL> - </TD> - - </TD> - </TABLE> - - <HR><P> - Back to the <A - HREF="http://www.cs.wustl.edu/~schmidt/ACE-documentation.html">ACE - documentation</A> page. - - <!--#include virtual="/~schmidt/cgi-sig.html" --> - </BODY> -</HTML> diff --git a/docs/CE-status.txt b/docs/CE-status.txt deleted file mode 100644 index eb6ecb38dc5..00000000000 --- a/docs/CE-status.txt +++ /dev/null @@ -1,904 +0,0 @@ --*- mode: outline; outline-regexp: " *\\[" -*- - -This document presents the status of the ACE port to Windows CE. We -present hints on writing portable code using ACE on Windows CE and -other Win32 platforms. Moreover, we outline current unresolved -technical issues with the port and with Windows CE development tools. -Finally, we describe the status of all the ACE regression tests on -Windows CE. - -[Hints on writing portable code using ACE] - - [Testing Non-Window based ACE programs] - Rumor has it that Microsoft will provide a DOS shell in their - next release of CE. Oh well, I made it up and there'll probably - no DOS prompt in the future CE. All current ACE programs are - text-based. They all need a shell to start from. - - [Dialog Based] - This is a collection of files that combined with any ACE - program to run on CE. To use this template, compile your main - project with all the cpp and rc files under $ACE_ROOT/windoezCE/. - - The program will start by asking you the command line argument - that you want to pass to the original ACE program. We should be - able to get this infomation automatically if we execute the - program from "Start -> Run...". However, that'll require us to - implement this window using Win32 API (it's written with MFC - classes now.) Notice that GetCommandLine is not available on - CE. - - [Future Improvement] - - Get the command line argument automatically. - - Buffered keyboard input (stdin.) - - Scrollable output. - - [Unicode Trivia] - Since most APIs take wide char strings as their arguments when - strings are needed, some pre-cautions must be taken... - - Here are some macros that help converting string types back - and forth based on your platform settings. Here, under CE is - equivalent to have ACE_HAS_MOSTLY_UNICODE_APIS defined. - - [ASYS_TCHAR] Defined as wchar_t under CE, but as char under all - other paltforms. - - [ASYS_TEXT] A macro that converts a char text to a wchar text - only under CE. - - [ASYS_WIDE_STRING] A macro that converts char strings to wchar - strings using ACE_WString only when - ACE_HAS_MOSTLY_UNICODE_APIS is defined. - - [ASYS_MULTIBYTE_STRING] A macro that converts wchar strings to - char strings using ACE_WString while - ACE_HAS_MOSTLY_UNICODE_APIS is not defined but UNICODE is - defined. - - [ASYS_ONLY_MULTIBYTE_STRING] Like ASYS_MULTIBYTE_STRING but only - convert a string when ACE_HAS_MOSTLY_UNICODE_APIS defined and - UNICODE not defined. - - [ACE_TRACE] When using ACE_TRACE macros, you don't need to use - wide char string in it. ACE converts the char string to wchar - string for you. - -[Current difficulties] - - [Bugs in cross compiler for SH series CPU] - - [Inline functions] - are not supported at least for debug build for DLL. I have to - un-inline _all_ inline functions in ACE to get it to work. - Not sure if inlining works for Release version or other CPUs - (namely, MIPS series.) It appears to work fine for x86 - emulator builds. - - [Lost string literals] - The following format string in ACE_OS::ctime_r was - misteriously replaced with garbage by SH compiler: - - ACE_OS::sprintf (buf, __TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n"),..... - - The solution for this is to define the format string in global - namespace as: - - static const ASYS_TCHAR *fmtstr = __TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n"); - - And call the sprintf as: - - ACE_OS::sprintf (buf, fmtstr,....); - - There doesn't seem to be any recognizable pattern on how this - will happen (otherwise, I'll call this a feature.) - -[HPC issues] - The only testbed we have locally is an HP 360LX. Some tests that - use sockets must have the ethernet card installed in order to run - successfully. If you don't, the test will either hang or worse, - render the serial connection unusable. - - Sometimes, some programs will screw up the whole system - completely. Reset button is you best friend when this happens. - - -[CE Toolkit issues] - - [CE Toolkit] - Using CE toolkit for C++ is simply a pain in the ass. It takes - around 30 seconds to start up a debug session and 5+ seconds to - single step thru a statement. It only allows remote debugging - using the serial link but not the network. (BTW, currently, CE - only support NE2000 compatible PCMCIA ethernet card.) - - [SH3 compiler] - * The SH3 compiler does not generate string literals when they - are used inside a function and when a precompiled header is - also used. This problem can be seen when a variable inside a - function is defined by initializing it to a string literal. Two - solutions are available: - - - Use a global variable, if you want to initialize it to a - string literal, or - - Do not use precompiled headers if you initialize a - variable, defined inside a function, with a string - literal. - - * The SH3 compiler generates a fatal internal error, when - __declspec(dllimport) is used for a class with a virtual - function in it. To avoid the internal error, change the - imported class to not use any virtual functions. - - -[Tidbits] - - [Web resources] - - http://www.sockets.com/ws_wince.htm - - [FILETIME] - - Win32's FILETIME format can be converted to struct timeval thru a - simple conversion. However, the tricky part here is, FILETIME is - the total 100ns elapse since _1601_ (why the heck did Microsoft - choose this time?) whereas POSIX timeval gives you the - accumulated time in us since 1970. This leads to data overflow - in timeval struture which ACE uses internally for its - ACE_Time_Value. This also confuses ACE_OS::ctime, which, under - CE, is a home-brewed implementation, and corrupt the whole - program image. I don't know of a way to deal with this yet - except adjusting for the time difference between the two - everytime a conversion is necessary. This, of course, doesn't - seem to be a good choice. - - - -[Status of one-button tests] - - [Convention of project files settings] - - Procedures: - - * Create a new "Win32 Application" project file. It should - support the following platforms: WCE x86em, WCE MIPS, and WCE - SH3. Notice the project location should Be under - $ACE_ROOT/tests/WinCE. - - * Add the cpp file(s) along with all .cpp and .rc files under - $ACE_ROOT/WindozeCE. - - * Open Project settings. - - * General Settings are: - "Using MFC in a Shared DLL" for all platforms. - Both "Intermediate files" and "Output files" should be the - same path. They should be one of "x86emDbg", "WMIPSDbg", and - "WCESHDbg" depend on the target platform. - - * "C/C++" Settings: - Add "ACE_HAS_DLL=1", "ACE_HAS_WINCE" to preprocessor - definitions for all target platforms. - Set "Code Generation" -> "Use run-time library" to "Debug - Multithreaded". - Add to "Preprocessor" -> "Additional include directories" the - following: "..\,..\..\,..\..\WindozeCE\". - - * "Link" Settings: - Added "aced.lib" into "Input" -> "Object/library modules". - Set "Input" -> "Additional library path" according to the - target platform. It should one of the following: - "..\..\ace\WCE\x86em", - "..\..\ace\WCE\MIPS", or, - "..\..\ace\WCE\SH". - - * You are all done. - - [Legend:] - X - test working properly - F - compile but doesn't work correctly. - C - compilation trouble - . - work pending (deferred) - N - Not supported by CE - - For each test, Section [EM] describes the status of the test - on x86 emulator. Section [SH] describes the status of the - test under SH series machines. (I use an HP 360LX as my - testbed.) [MIPS] information is unavailable at the moment. - - [N] Aio_Platform_Test - Asynch I/O is not supported on CE. - [X] Atomic_Op_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Barrier_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Basic_Types_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Buffer_Stream_Test - [EM] Runs successfully - [SH] Runs successfully - [F] Conn_Test - [EM] Runs successfully - [SH] Hangs at halfway. (Can't have two server threads - running at the same time.) - I managed the test to run to completion when setting n_server = 1 and - n_client = 4. But I don't think that considered a successful run. - [X] Enum_Interfaces_Test - Sort of working right. - [EM] Report get_ip_interface error - [SH] Report get_ip_interface error - [N] Env_Value_Test - [X] Future_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Handle_Set_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Hash_Map_Manager_Test - [EM] Runs successfully - [SH] Runs successfully - [N] IOStream_Test - ??? - [N] MM_Shared_Memory_Test - ??? - [X] MT_SOCK_Test - This one takes some time.....zzzzz..... - [EM] Runs successfully - [SH] Runs if client threads reduced to 5. - (And I reverted my change back, so it won't runs on our - HP 360LX.) - [X] Map_Manager_Test - [EM] Runs successfully - [SH] Runs successfully - [F] Mem_Map_Test - [EM] - [SH] - [X] Message_Block_Test - inline functions in auto-generated ctors. - [EM] Runs successfully - [SH] Runs successfully - [F] Message_Queue_Notifications_Test - Hang at termination. - [EM] Runs successfully - [SH] There appears to be more compiler bugs that affect -this test. The notify pipe used by the reactor was not set to -non-blocking mode and thus the test hang at termination. I was not -able to set any break points into places I wanted. CE sucks. - [X] Message_Queue_Test - [EM] Runs successfully - [SH] Runs successfully - [.] Naming_Test - Registry is not added into CE yet. - [F] Notify_Performance_Test - [EM] Runs successfully - [SH] ??? - [X] OrdMultiSet_Test - [EM] Runs successfully - [SH] Runs successfully - [N] Pipe_Test - This test will have to rewriten in ACE. - [X] Priority_Buffer_Test - [EM] Runs successfully - [SH] Runs successfully - [N] Priority_Reactor_Test - Not supported yet. - [X] Priority_Task_Test - [EM] Runs successfully - [SH] Runs successfully - [N] Process_Mutex_Test - Don't know how to start a process as a console application. - [N] Process_Strategy_Test - Let's skip process related tests for now. - [N] Reactor_Exceptions_Test - Exceptions are not support on CE. - [F] Reactor_Notify_Test - Hang at "starting limited notifications test." - [EM] Runs successfully - [SH] ??? - [F] Reactor_Performance_Test - [EM] Runs successfully - [SH] ??? - [X] Reactor_Timer_Test - [EM] Runs successfully - [SH] Runs successfully - [F] Reactors_Test - Hang after done_count reaches 0. Reactors were not shutting down. - [EM] ??? - [SH] - [X] Reader_Writer_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Recursive_Mutex_Test - The test succeeded after reducing the iteration from 100 to - 50. It appears that windows' CEdit buffer overflowed from - the exccessive amount of output from this test. - [EM] Runs successfully - [SH] Runs successfully - [X] SOCK_Connector_Test - [EM] Runs successfully - [SH] Runs successfully - [X] SOCK_Test - [EM] Runs successfully - [SH] Runs successfully - [N] SPIPE_Test - SPIPE is not supported yet. - [X] SString_Test - [EM] Runs successfully - [SH] Runs successfully - [N] SV_Shared_Memory_Test - [X] Semaphore_Test - [EM] Runs successfully - [SH] Runs successfully - [.] Service_Config_Test - I don't have confidence on this test.... - [X] Sigset_Ops_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Simple_Message_Block_Test - [EM] Runs successfully - [SH] Runs successfully - [X] TSS_Test - TlsGetValue appearently acts differently from most Win32 - platforms. If we check the return value and the error - code, then, ACE_OS::key_getspecific will never succeed. - [EM] Runs successfully - [SH] Runs successfully - [X] Task_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Thread_Manager_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Thread_Mutex_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Thread_Pool_Test - [EM] Runs successfully - [SH] Runs successfully - [.] Time_Service_Test - [X] Time_Value_Test - [EM] Runs successfully - [SH] Runs successfully - [X] Timer_Queue_Test - [EM] Runs successfully - [SH] Runs successfully - [.] Tokens_Test - [N] UPIPE_SAP_Test - - -[ACE File list] - Here is a trace of ACE files about their status on CE. - [Legend] - (.) Defered. - (x) Compiled successfully. (Doesn't mean it will run. ;-) - (@) Not compile yet. - (T) Template codes. - (N) Not planning to support - ( ) ??? - - [ACE] - [CORBA] - (.) CORBA_Handler.cpp - (.) CORBA_Handler.h - (.) CORBA_Handler.i - (.) CORBA_Ref.cpp - (.) CORBA_Ref.h - (.) CORBA_Ref.i - [Collections] - (x) Array.cpp - (x) Array.h - (x) Array.i - (T) Containers.cpp - (T) Containers.i - (T) Containers.h - (T) Hash_Map_Manager.cpp - (T) Hash_Map_Manager.h - (T) Filecache.cpp - (T) Filecache.h - (T) Free_List.cpp - (T) Free_List.i - (T) Free_List.h - (T) Managed_Object.cpp - (T) Managed_Object.h - (T) Managed_Object.i - (T) Map_Manager.cpp - (T) Map_Manager.h - (T) Map_Manager.i - (x) Object_Manager.cpp - (x) Object_Manager.i - (x) Object_Manager.h - (x) SString.cpp - (x) SString.h - (x) SString.i - [Concurrency] - (x) Activation_Queue.h - (x) Activation_Queue.cpp - (x) Atomic_Op.i - (.) Future.h - (.) Future.cpp - (x) Method_Object.h - (x) Method_Object.cpp - (x) Process.cpp - (x) Process.h - (x) Process.i - (x) Process_Manager.cpp - (x) Process_Manager.h - (x) Process_Manager.i - (x) Sched_Params.cpp - (x) Sched_Params.h - (x) Sched_Params.i - (x) Synch.cpp - (x) Synch.h - (x) Synch.i - (x) Synch_Options.cpp - (x) Synch_Options.h - (x) Synch_Options.i - (T) Synch_T.cpp - (T) Synch_T.h - (T) Synch_T.i - (x) Thread.cpp - (x) Thread.h - (x) Thread.i - (x) Thread_Manager.cpp - (x) Thread_Manager.h - (x) Thread_Manager.i - (x) Token.cpp - (x) Token.h - (x) Token.i - [Config] - (x) config.h - (x) Basic_Types.cpp - (x) Basic_Types.h - (x) Basic_Types.i - (x) Version.h - [Connection] - (T) Acceptor.cpp - (T) Acceptor.h - (T) Acceptor.i - (.) Asynch_Acceptor.cpp - (.) Asynch_Acceptor.h - (.) Asynch_Acceptor.i - (x) Asynch_IO.cpp - (x) Asynch_IO.h - (x) Asynch_IO.i - (T) Connector.cpp - (T) Connector.h - (T) Connector.i - (T) Dynamic_Service.cpp - (T) Dynamic_Service.h - (T) Dynamic_Service.i - (x) Strategies.cpp - (x) Strategies.h - (x) Strategies.i - (T) Strategies_T.cpp - (T) Strategies_T.h - (T) Strategies_T.i - (T) Svc_Handler.cpp - (T) Svc_Handler.h - (T) Svc_Handler.i - [IPC] - [IO_SAP] - (x) IO_SAP.cpp - (x) IO_SAP.h - (x) IO_SAP.i - [DEV_SAP] - (N) DEV.cpp - (N) DEV.h - (N) DEV.i - (N) DEV_Connector.cpp - (N) DEV_Connector.h - (N) DEV_Connector.i - (N) DEV_IO.cpp - (N) DEV_IO.h - (N) DEV_IO.i - (N) TTY_IO.cpp - (N) TTY_IO.h - [FILE_SAP] - (.) FILE.cpp - (.) FILE.h - (.) FILE.i - (.) FILE_Connector.cpp - (.) FILE_Connector.h - (.) FILE_Connector.i - (.) FILE_IO.cpp - (.) FILE_IO.h - (.) FILE_IO.i - [IPC_SAP] - (x) IPC_SAP.cpp - (x) IPC_SAP.h - (x) IPC_SAP.i - [Addr] - (x) Addr.cpp - (x) Addr.h - (x) Addr.i - (N) DEV_Addr.cpp - (N) DEV_Addr.h - (N) DEV_Addr.i - (.) FILE_Addr.cpp - (.) FILE_Addr.h - (.) FILE_Addr.i - (x) INET_Addr.cpp - (x) INET_Addr.h - (x) INET_Addr.i - (.) SPIPE_Addr.cpp - (.) SPIPE_Addr.h - (.) SPIPE_Addr.i - (N) UNIX_Addr.cpp - (N) UNIX_Addr.h - (N) UNIX_Addr.i - (.) UPIPE_Addr.h - [FIFO_SAP] - (.) FIFO.cpp - (.) FIFO.h - (.) FIFO.i - (.) FIFO_Recv.cpp - (.) FIFO_Recv.h - (.) FIFO_Recv.i - (.) FIFO_Recv_Msg.cpp - (.) FIFO_Recv_Msg.h - (.) FIFO_Recv_Msg.i - (.) FIFO_Send.cpp - (.) FIFO_Send.h - (.) FIFO_Send.i - (.) FIFO_Send_Msg.cpp - (.) FIFO_Send_Msg.h - (.) FIFO_Send_Msg.i - [SOCK_SAP] - ( ) LOCK_SOCK_Acceptor.cpp - ( ) LOCK_SOCK_Acceptor.h - ( ) LSOCK.cpp - ( ) LSOCK.h - ( ) LSOCK.i - ( ) LSOCK_Acceptor.cpp - ( ) LSOCK_Acceptor.h - ( ) LSOCK_Acceptor.i - ( ) LSOCK_CODgram.cpp - ( ) LSOCK_CODgram.h - ( ) LSOCK_CODgram.i - ( ) LSOCK_Connector.cpp - ( ) LSOCK_Connector.h - ( ) LSOCK_Connector.i - ( ) LSOCK_Dgram.cpp - ( ) LSOCK_Dgram.h - ( ) LSOCK_Dgram.i - ( ) LSOCK_Stream.cpp - ( ) LSOCK_Stream.h - ( ) LSOCK_Stream.i - (x) SOCK.cpp - (x) SOCK.h - (x) SOCK.i - (x) SOCK_Acceptor.cpp - (x) SOCK_Acceptor.h - (x) SOCK_Acceptor.i - (x) SOCK_CODgram.cpp - (x) SOCK_CODgram.h - (x) SOCK_CODgram.i - (x) SOCK_Connector.cpp - (x) SOCK_Connector.h - (x) SOCK_Connector.i - (x) SOCK_Dgram.cpp - (x) SOCK_Dgram.h - (x) SOCK_Dgram.i - (x) SOCK_Dgram_Bcast.cpp - (x) SOCK_Dgram_Bcast.h - (x) SOCK_Dgram_Bcast.i - (x) SOCK_Dgram_Mcast.cpp - (x) SOCK_Dgram_Mcast.h - (x) SOCK_Dgram_Mcast.i - (x) SOCK_IO.cpp - (x) SOCK_IO.h - (x) SOCK_IO.i - (x) SOCK_Stream.cpp - (x) SOCK_Stream.h - (x) SOCK_Stream.i - [SPIPE_SAP] - (.) SPIPE.cpp - (.) SPIPE.h - (.) SPIPE.i - (.) SPIPE_Acceptor.cpp - (.) SPIPE_Acceptor.h - (.) SPIPE_Acceptor.i - (.) SPIPE_Connector.cpp - (.) SPIPE_Connector.h - (.) SPIPE_Connector.i - (.) SPIPE_Stream.cpp - (.) SPIPE_Stream.h - (.) SPIPE_Stream.i - [TLI_SAP] - (N) TLI.cpp - (N) TLI.h - (N) TLI.i - (N) TLI_Acceptor.cpp - (N) TLI_Acceptor.h - (N) TLI_Acceptor.i - (N) TLI_Connector.cpp - (N) TLI_Connector.h - (N) TLI_Connector.i - (N) TLI_Stream.cpp - (N) TLI_Stream.h - (N) TLI_Stream.i - [UPIPE_SAP] - (N) UPIPE_Acceptor.cpp - (N) UPIPE_Acceptor.h - (N) UPIPE_Acceptor.i - (N) UPIPE_Connector.cpp - (N) UPIPE_Connector.h - (N) UPIPE_Connector.i - (N) UPIPE_Stream.cpp - (N) UPIPE_Stream.h - (N) UPIPE_Stream.i - [Utils] - (N) IOStream.cpp // CE doesn't have iostream stuff - (N) IOStream.h - (N) IOStream_T.cpp - (N) IOStream_T.h - (N) IOStream_T.i - (x) Pipe.cpp - (x) Pipe.h - (x) Pipe.i - (x) Signal.cpp - (x) Signal.h - (x) Signal.i - [Logging and Tracing] - (x) Dump.cpp - (x) Dump.h - (x) Dump_T.cpp - (T) Dump_T.h - (T) Log_Msg.cpp - (x) Log_Msg.h - (x) Log_Msg.i - (x) Log_Priority.h - (x) Log_Record.cpp - (x) Log_Record.h - (x) Log_Record.i - (x) Trace.cpp - (x) Trace.h - (x) Trace.i - [Memory] - [Mem_Map] - (x) Mem_Map.cpp - (x) Mem_Map.h - (x) Mem_Map.i - [Shared_Malloc] - (x) Malloc.cpp - (x_) Malloc.h - (x) Malloc.i - (T) Malloc_T.cpp - (T) Malloc_T.h - (T) Malloc_T.i - (x) Memory_Pool.cpp - (x_) Memory_Pool.h - (x) Memory_Pool.i - [Shared_Memory] - ( ) Shared_Memory.h - ( ) Shared_Memory_MM.cpp - ( ) Shared_Memory_MM.h - ( ) Shared_Memory_MM.i - ( ) Shared_Memory_SV.cpp - ( ) Shared_Memory_SV.h - ( ) Shared_Memory_SV.i - [Utils] - (x) Obstack.cpp - (x) Obstack.h - (@) Read_Buffer.cpp - (@) Read_Buffer.h - (@) Read_Buffer.i - [Misc] - (x) ARGV.cpp - (x) ARGV.h - (x) ARGV.i - (T) Auto_Ptr.cpp - (T) Auto_Ptr.h - (T) Auto_Ptr.i - (x) Dynamic.cpp - (x) Dynamic.h - (x) Dynamic.i - (x) Get_Opt.cpp - (x) Get_Opt.h - (x) Get_Opt.i - (.) Registry.cpp - (.) Registry.h - (T) Singleton.cpp - (T) Singleton.h - (T) Singleton.i - (x) System_Time.cpp - (x) System_Time.h - [Name_Service] - (.) Local_Name_Space.cpp - (.) Local_Name_Space.h - (.) Local_Name_Space_T.cpp - (.) Local_Name_Space_T.h - (.) Name_Options.cpp - (.) Name_Options.h - (.) Name_Proxy.cpp - (.) Name_Proxy.h - (.) Name_Request_Reply.cpp - (.) Name_Request_Reply.h - (.) Name_Space.cpp - (.) Name_Space.h - (.) Naming_Context.cpp - (.) Naming_Context.h - (.) Registry_Name_Space.cpp - (.) Registry_Name_Space.h - (.) Remote_Name_Space.cpp - (.) Remote_Name_Space.h - [OS Adapters] - (x) ACE.cpp - (x) ACE.h - (x) ACE.i - (x) OS.cpp - (x) OS.h - (x) OS.i - [Reactor] - (x) Event_Handler.cpp - (x) Event_Handler.h - (x) Event_Handler.i - (T) Event_Handler_T.cpp - (T) Event_Handler_T.h - (T) Event_Handler_T.i - (x) Handle_Set.cpp - (x) Handle_Set.h - (x) Handle_Set.i - ( ) Priority_Reactor.cpp - ( ) Priority_Reactor.i - ( ) Priority_Reactor.h - ( ) Proactor.h - ( ) Proactor.i - ( ) Proactor.cpp - (x) Reactor.cpp - (x) Reactor.h - (x) Reactor.i - (x) Reactor_Impl.h - (x) Select_Reactor.cpp - (x) Select_Reactor.h - (x) Select_Reactor.i - (@) WFMO_Reactor.cpp - (@) WFMO_Reactor.h - (@) WFMO_Reactor.i - (x) XtReactor.cpp - (x) XtReactor.h - [Service_Configurator] - (x) Parse_Node.cpp - (x) Parse_Node.h - (x) Parse_Node.i - (x) Service_Config.cpp - (x) Service_Config.h - (x) Service_Config.i - (x) Service_Manager.cpp - (x) Service_Manager.h - (x) Service_Manager.i - (x) Service_Object.cpp - (x) Service_Object.h - (x) Service_Object.i - (x) Service_Repository.cpp - (x) Service_Repository.h - (x) Service_Repository.i - (x) Service_Types.cpp - (x) Service_Types.i - (x) Service_Types.h - (x) Shared_Object.cpp - (x) Shared_Object.h - (x) Shared_Object.i - (x) Svc_Conf.h - (x) Svc_Conf_l.cpp - (x) Svc_Conf_y.cpp - [Streams] - (x) IO_Cntl_Msg.cpp - (x_) IO_Cntl_Msg.h - (x) IO_Cntl_Msg.i - (x) Message_Block.cpp - (x) Message_Block.h - (x) Message_Block.i - (T) Message_Queue.cpp - (T) Message_Queue.h - (T) Message_Queue.i - (T) Module.cpp - (T) Module.h - (T) Module.i - (.) Multiplexor.cpp - (.) Multiplexor.h - (.) Multiplexor.i - (T) Stream.cpp - (T) Stream.h - (T) Stream.i - (T) Stream_Modules.cpp - (T) Stream_Modules.h - (T) Stream_Modules.i - (x) Task.cpp - (x) Task.h - (x) Task.i - (T) Task_T.cpp - (T) Task_T.h - (T) Task_T.i - [System_V_IPC] - [System_V_Message_Queues] - ( ) SV_Message.cpp - ( ) SV_Message.h - ( ) SV_Message.i - ( ) SV_Message_Queue.cpp - ( ) SV_Message_Queue.h - ( ) SV_Message_Queue.i - ( ) Typed_SV_Message.cpp - ( ) Typed_SV_Message.h - ( ) Typed_SV_Message.i - ( ) Typed_SV_Message_Queue.cpp - ( ) Typed_SV_Message_Queue.h - ( ) Typed_SV_Message_Queue.i - [System_V_Semaphores] - ( ) SV_Semaphore_Complex.cpp - ( ) SV_Semaphore_Complex.h - ( ) SV_Semaphore_Complex.i - ( ) SV_Semaphore_Simple.cpp - ( ) SV_Semaphore_Simple.h - ( ) SV_Semaphore_Simple.i - [System_V_Shared_Memory] - ( ) SV_Shared_Memory.cpp - ( ) SV_Shared_Memory.h - ( ) SV_Shared_Memory.i - [Timers] - - (x) High_Res_Timer.cpp - (x) High_Res_Timer.h - (x) High_Res_Timer.i - (x) Profile_Timer.cpp - (x) Profile_Timer.h - (x) Profile_Timer.i - (.) Time_Request_Reply.cpp - (.) Time_Request_Reply.h - (x) Time_Value.h - (x) Timer_Hash.cpp - (x) Timer_Hash.h - (T) Timer_Hash_T.cpp - (T) Timer_Hash_T.h - (x) Timer_Heap.cpp - (x) Timer_Heap.h - (x) Timer_Heap.i - (T) Timer_Heap_T.cpp - (T) Timer_Heap_T.h - (T) Timer_Heap_T.i - (x) Timer_List.cpp - (x) Timer_List.h - (x) Timer_List.i - (T) Timer_List_T.cpp - (T) Timer_List_T.h - (T) Timer_List_T.i - (x) Timer_Queue.cpp - (x) Timer_Queue.h - (x) Timer_Queue.i - (T) Timer_Queue_Adapters.cpp - (T) Timer_Queue_Adapters.h - (T) Timer_Queue_Adapters.i - (T) Timer_Queue_T.cpp - (T) Timer_Queue_T.h - (T) Timer_Queue_T.i - (x) Timer_Wheel.cpp - (x) Timer_Wheel.h - (x) Timer_Wheel.i - (T) Timer_Wheel_T.cpp - (T) Timer_Wheel_T.h - (T) Timer_Wheel_T.i - [Token_Service] - (x) Local_Tokens.cpp - (x) Local_Tokens.h - (x) Local_Tokens.i - (.) Remote_Tokens.cpp - (.) Remote_Tokens.h - (.) Remote_Tokens.i - (.) Token_Collection.cpp - (.) Token_Collection.h - (.) Token_Collection.i - (x) Token_Manager.cpp - (x) Token_Manager.h - (x) Token_Manager.i - (.) Token_Request_Reply.cpp - (.) Token_Request_Reply.h - (.) Token_Request_Reply.i - (.) Token_Invariants.h - (.) Token_Invariants.i - (.) Token_Invariants.cpp diff --git a/docs/exceptions.html b/docs/exceptions.html deleted file mode 100644 index c90f90970b6..00000000000 --- a/docs/exceptions.html +++ /dev/null @@ -1,243 +0,0 @@ -<!DOCTYPE HTML SYSTEM -"http://www.w3.org/pub/WWW/MarkUp/Cougar/Cougar.dtd"> -<!-- $Id$ --> -<html> <head> -<title>Using ACE try macros for CORBA programming</title> -</head> - -<body> -<h1>Using ACE try macros for CORBA programming</h1> - -CORBA::Environment provides a way for exception handling when native -c++ exception handling is unavailable or undesirable. However, writing -portable code for both (with and without) native exception handling -capability is very hairy. ACE provides a set of macros to help dealing -with the chaos. - -<h3>In a Nutshell</h3> - -This section explains some simple rules of writing programs for -platforms with and without native exception support using ACE's try -macros. - -<ol> - <li><em>Name of CORBA::Environment variable</em><br> - A function that may throw a CORBA::Exception needs a - CORBA::Environment variable to pass up exceptions and to gather - exceptions from functions it called. By default, ACE try macros - assume the variable is named <code>ACE_TRY_ENV</code>. - <code>ACE_TRY_ENV</code> itself is also a macro which can be - redefined. If you are using TAO, more likely than not, you - don't have to worry about redefining this macro because TAO - is written to use ACE try macros. For example, you should - define your functions as, - <pre> - int AN_OBJ::foobar (int a, int b, CORBA_Environment &ACE_TRY_ENV); - </pre> - and within the function, call other functions that might throw - exceptions like, - <pre> - another_obj->func_name (x, y, ACE_TRY_ENV); - </pre><p> - - As mentioned, you can redefine the name of the variable to - something else to avoid name clashing. Alternatively, there's - another macro (<code>ACE_ADOPT_CORBA_ENV</code>) that allow you - to use another variable name as the default CORBA::Environment - <em>within</em> a function. - - <li><em>Throwing exceptions:</em><br> - Use <code>ACE_THROW</code> and <code>ACE_THROW_RETURN</code> to - throw exceptions. They should never be used withing a try - block.<p> - - <li><em>Propagating exceptions:</em><br> - To simulate native exceptions on platforms without native - exception handling, <em>every</em> single function call that may - throw exceptions must be followed by <code>ACE_CHECK</code> or - <code>ACE_CHECK_RETURN</code>. Notice that you should always - follow the outter most <code>ACE_ENDTRY</code> with - <code>ACE_CHECK</code> or <code>ACE_CHECK_RETURN</code> because - there might be uncaught exception.<p> - - You should pass <code>ACE_TRY_ENV</code> to these functions.<p> - - Be very careful not to combine exception throwing functions in - one statement like this: - </pre> - x = obj1->callme (ACE_TRY_ENV) + obj2->dare_me (ACE_TRY_ENV); - ACE_CHECK; - <pre> - This example may work differently when native exception handling - is enabled/disabled.<p> - - <li><em>Catching exceptions:</em><br> - Use <code>ACE_TRY</code> to catch exceptions if there's an - <code>ACE_TRY_ENV</code> available. Otherwise, use - <code>ACE_TRY_NEW_ENV</code>. If there are more than one try - blocks in a function, use <code>ACE_TRY_EX</code> for all - subsequence try blocks to avoid name clashing of labels.<p> - <ul> - <li>Within a <code>ACE_TRY</code> block, use the variable - <code>ACE_TRY_ENV</code> to pass down the - <code>CORBA_Environment</code> (see <a - href="#try_env">this</a> example.) <p> - - <li>Follow <em>every</em> exception throwing function with - <code>ACE_TRY_CHECK</code>, including inner - <code>ACE_ENDTRY</code>.<p> - - <li>Use <code>ACE_CATCH</code> to catch exceptions of certain - type. <p> - - <li><code>ACE_CATCHANY</code> catches <em>any</em> exceptions - of type <code>CORBA_Exception</code>.<p> - - <li>Use <code>ACE_RETHROW</code> to rethrow the same exception - within a <code>ACE_CATCH</code> or - <code>ACE_CATCHANY</code> block.<p> - - <li>A <code>ACE_TRY</code> block must be terminated with a - <code>ACE_ENDTRY</code> statement.<p> - - <li>Throw an exception within a <code>ACE_TRY</code> block or - <code>ACE_CATCH</code> block using <a href="#try_throw"> - <code> ACE_TRY_THROW</code></a>.<p> - </ul><p> - -</ol> - -<h3>Examples</h3> - -Refer to <a href="../ace/CORBA_macros.h"><code> -$ACE_ROOT/ace/CORBA_macros.h</code></a> for complete definitions of -macros discussed here. - -<ul>Sample exception catching: -<pre> - ACE_TRY - { - some_operation (arg1, arg2, ACE_TRY_ENV); - ACE_TRY_CHECK; - - . - . - if (whatever) - ACE_TRY_THROW (CORBA::BadParam); - - some_other_operation (arg1, arg2, arg3, ACE_TRY_ENV); - ACE_TRY_CHECK; - } - ACE_CATCH (CORBA_some_exception, ex) - { - // error handling. - if (still_has_error) - ACE_TRY_THROW (CORBA::NOWAY); - } - ACE_CATCHANY - { - // error handling. - // then rethow the exception. - ACE_RETHROW; - } - ACE_ENDTRY; - ACE_CHECK; -</pre><br> - - <li><code>ACE_TRY</code> and also declares a label (so do - <code>ACE_TRY_NEW_ENV</code>. To avoid defining the - same label multiple times within a function, use - <code>ACE_TRY_EX</code> with different labels for different try - blocks instead. For example,<br> - -<pre> - ACE_TRY_EX (block_1) - { - some_operation (arg1, arg2, ACE_TRY_ENV); - ACE_TRY_CHECK_EX (block_1); - - some_other_operation (arg1, arg2, arg3, ACE_TRY_ENV); - ACE_TRY_CHECK_EX (block_1); - } - ACE_CATCH (CORBA_some_exception, ex) - { - // error handling. - } - ACE_CATCHANY - { - // error handling. - } - ACE_ENDTRY; - ACE_CHECK_RETURN (-1); - - // Some other operation here - // . - // . - // . - // . - - ACE_TRY_EX (block_2) - { - foo (arg, ACE_TRY_ENV); - ACE_TRY_CHECK_EX (block_2); - - bar (arg1, arg2, ACE_TRY_ENV); - ACE_TRY_CHECK_EX (block_2); - } - ACE_CATCH (CORBA_some_exception, ex) - { - // error handling. - } - ACE_CATCHANY - { - // error handling. - } - ACE_ENDTRY; - ACE_CHECK_RETURN (-1); -</pre><p> - - <li>Be <em>VERY</em> wary of <code>ACE_CATCHALL</code>. It catches - exceptions of any type. If your program depends on it, then, - more often than not, there're something wrong with it.<p> - - <li>Instead of depending on <code>ACE_CATCHALL</code>, use - <code>auto_prt</code> style mechanism to prevent memory leaks - from exceptions.<p> -</ul> - -<h3>General Guidelines of Exceptions</h3> -<ul> - <li>Don't catch an exception just to rethrow it. Exceptions cost - you performance.<p> - - <li>When exceptions occur, make sure an object's is still in - a valid state or change to a state that can be safely - destructed.<p> - - <li>Watch out for side effect in the expression which may cause - exceptions. In the following example, what should - <code>i</code> be if an exception does occur?<br> -<pre> - ACE_TRY - { - obj[i++] = foo_bar_method (a, b, ACE_TRY_ENV); - } -</pre><p> - - <li>Make sure an exception doesn't cause resource leak (memory, - socket, ...) (hint: Use auto_ptr to avoid memory leak.)<p> - - <li>Don't catch any exception that you don't know how to handle.<p> - - <li>Never throw an exception from destructor (unless you know what - it implies.)<p> - - <li>Use exceptions to provide more information about the error.<p> - - <li>Rethrow a different exception only to provide <em>more</em> - information. Do not catch an exception just to rethrow, say, - <code>unknow_exception</code>.<p> - -</ul> -<!--#include virtual="/~schmidt/cgi-sig.html" --> -</body></HTML> diff --git a/docs/tutorials/001/001.dsp b/docs/tutorials/001/001.dsp deleted file mode 100644 index 196a498962a..00000000000 --- a/docs/tutorials/001/001.dsp +++ /dev/null @@ -1,108 +0,0 @@ -# Microsoft Developer Studio Project File - Name="001" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=001 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "001.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "001.mak" CFG="001 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "001 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "001 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "001 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "001 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "001 - Win32 Release"
-# Name "001 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\acceptor.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\logger.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/001/00SetEnv b/docs/tutorials/001/00SetEnv deleted file mode 100644 index eca78e10c85..00000000000 --- a/docs/tutorials/001/00SetEnv +++ /dev/null @@ -1,2 +0,0 @@ -export ACE_ROOT=/local/src/ACE/ACE_wrappers -export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH diff --git a/docs/tutorials/001/Makefile b/docs/tutorials/001/Makefile deleted file mode 100644 index 88cbcd3b69c..00000000000 --- a/docs/tutorials/001/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for the Reactor Server Logging Daemon -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server - -FILES = - -LSRC = $(addsuffix .cpp,$(FILES)) -LOBJ = $(addsuffix .o,$(FILES)) -SHOBJ = $(addsuffix .so,$(FILES)) - -LDLIBS = $(addprefix .shobj/,$(SHOBJ)) - -VLDLIBS = $(LDLIBS:%=%$(VAR)) - -BUILD = $(VBIN) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -.obj/server.o .shobj/server.so: server.cpp acceptor.h logger.h - diff --git a/docs/tutorials/001/Source.tgz b/docs/tutorials/001/Source.tgz Binary files differdeleted file mode 100644 index d88891aaf22..00000000000 --- a/docs/tutorials/001/Source.tgz +++ /dev/null diff --git a/docs/tutorials/001/acceptor.h b/docs/tutorials/001/acceptor.h deleted file mode 100644 index 2556f0ab324..00000000000 --- a/docs/tutorials/001/acceptor.h +++ /dev/null @@ -1,148 +0,0 @@ - -// $Id$ - - -#ifndef _CLIENT_ACCEPTOR_H -#define _CLIENT_ACCEPTOR_H - -/* - A SOCK_Acceptor knows how to accept socket connections. We'll use - one of those at the heart of our Logging_Acceptor. - */ -#include "ace/SOCK_Acceptor.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - An Event_Handler is what you register with ACE_Reactor. When events occur, - the reactor will callback on the Event_Handler. More on that in a few lines. - */ -#include "ace/Event_Handler.h" - -/* - When a client connects, we'll create a Logging_Handler to deal with the - connection. Here, we bring in that declaration. - */ -#include "logger.h" - -/* - Our Logging_Acceptor is derived from ACE_Event_Handler. That lets the - reactor treat our acceptor just like every other handler. - */ -class Logging_Acceptor : public ACE_Event_Handler -{ -public: - - /* - For this simple case we won't bother with either constructor or - destructor. In a real application you would certainly have them. - */ - - /* - Here's the open() method we called from main(). We have two things - to accomplish here: (1) Open the acceptor so that we can hear - client requests and (2) register ourselves with the reactor so that - we can respond to those requests. - */ - int open (const ACE_INET_Addr &_addr, ACE_Reactor * _reactor ) - { - /* - Perform the open() on the acceptor. We pass through the address - at which main() wants us to listen. The second parameter tells - the acceptor it is OK to reuse the address. This is necessary - sometimes to get around closed connections that haven't timed out. - */ - if (this->peer_acceptor_.open (_addr, 1) == -1) - return -1; - - /* - Remember the reactor we're using. We'll need it later when we - create a client connection handler. - */ - reactor_ = _reactor; - - /* - Now we can register with the reactor we were given. Since the reactor - pointer is global, we could have just used that but it's gross enough - already. - Notice that we can pass 'this' right into the registration since we're - derived from ACE_Event_Handler. We also provide ACCEPT_MASK to tell - the reactor that we want to know about accept requests from clients. - */ - return _reactor->register_handler( this, ACE_Event_Handler::ACCEPT_MASK ); - } - -private: - - /* - To provide multi-OS abstraction, ACE uses the concept of "handles" for - connection endpoints. In Unix, this is a traditional file descriptor - (or integer). On other OS's, it may be something else. - The reactor will need to get the handle (file descriptor) to satisfy - it's own internal needs. Our relevant handle is the handle of the - acceptor object, so that's what we provide. - */ - ACE_HANDLE get_handle (void) const - { - return this->peer_acceptor_.get_handle (); - } - - /* - When an accept request arrives, the reactor will invoke the handle_input() - callback. This is where we deal with the connection request. - */ - virtual int handle_input (ACE_HANDLE _handle) - { - /* - The handle provided to us by the reactor is the one that triggered - our up-call. In some advanced situations, you might actually - register a single handler for multiple connections. The _handle - parameter is a way to sort 'em out. Since we don't use that - here, we simply ignore the parameter with the ACE_UNUSED_ARG() macro. - */ - ACE_UNUSED_ARG(_handle); - - /* - In response to the connection request, we create a new Logging_Handler. - This new object will be used to interact with the client until it - disconnects. - */ - Logging_Handler *svc_handler = new Logging_Handler; - - /* - To complete the connection, we invoke the accept() method call on - the acceptor object and provide it with the connection handler instance. - This transfers "ownership" of the connection from the acceptor to the - connection handler. - */ - if (this->peer_acceptor_.accept (*svc_handler) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p", "accept failed"), -1); - - /* - Again, most objects need to be open()ed before they are useful. We'll - give the handler our reactor pointer so that it can register for - events as well. If the open fails, we'll force a close(). - */ - if (svc_handler->open (reactor_) == -1) - svc_handler->close (); - - return 0; - } - -protected: - - /* - Our acceptor object instance - */ - ACE_SOCK_Acceptor peer_acceptor_; - - /* - A place to remember our reactor pointer - */ - ACE_Reactor * reactor_; -}; - -#endif /* _CLIENT_ACCEPTOR_H */ - diff --git a/docs/tutorials/001/logger.h b/docs/tutorials/001/logger.h deleted file mode 100644 index 46ed9fa2d02..00000000000 --- a/docs/tutorials/001/logger.h +++ /dev/null @@ -1,177 +0,0 @@ - -// $Id$ - - -#ifndef _CLIENT_HANDLER_H -#define _CLIENT_HANDLER_H - -/* - A connection handler will also be derived from ACE_Event_Handler so that we - can register with a reactor. - */ -#include "ace/Event_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/INET_Addr.h" - -/* - Since we're doing TCP/IP, we'll need a SOCK_Stream for the connection. - */ -#include "ace/SOCK_Stream.h" - -class Logging_Handler : public ACE_Event_Handler -{ -public: - - /* - Like the acceptor, we're simple enough to avoid constructor and destructor. - */ - - /* - To open the client handler, we have to register ourselves with the reactor. - Notice that we don't have to "open" our ACE_SOCK_Stream member variable. - Why? Because the call to the acceptor's accept() method took care of those - details for us. - */ - int open ( ACE_Reactor * _reactor ) - { - /* - Remember our reactor... - */ - reactor_ = _reactor; - - /* - In this case we're using the READ_MASK. Like the acceptor, handle_input() - will be called due to this mask but it's a nice piece of bookkeeping to - have separate masks for the separate types of activity. - */ - if (_reactor-> register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - return 0; - } - - /* - If we're explicitly closed we'll close our "file handle". The net result - is to close the connection to the client and remove ourselves from the - reactor if we're registered - */ - int close (void) - { - return this->handle_close (ACE_INVALID_HANDLE, ACE_Event_Handler::RWE_MASK); - } - - /* - This is a bit of magic... When we call the accept() method of the acceptor - object, it wants to do work on an ACE_SOCK_Stream. We have one of those as - our connection to the client but it would be gross to provide a method to - access that object. It's much cooler if the acceptor can just treat the - Logging_Handler as an ACE_SOCK_Stream. Providing this cast operator lets - that happen cleanly. - */ - operator ACE_SOCK_Stream &() - { - return this->cli_stream_; - } - -protected: - - /* - Again, like the acceptor, we need to provide the connection handle to the reactor. - */ - ACE_HANDLE get_handle (void) const - { - return this->cli_stream_.get_handle (); - } - - /* - And here's the handle_input(). This is really the workhorse of the application. - */ - virtual int handle_input (ACE_HANDLE) - { - /* - Create and initialize a small receive buffer. - */ - char buf[128]; - memset(buf,0,sizeof(buf)); - - /* - Invoke the recv() method of the ACE_SOCK_Stream to get some data. It will - return -1 if there is an error. Otherwise, it will return the number of bytes - read. Of course, if it read zero bytes then the connection must be gone. - How do I know that? Because handle_input() would not be called by the reactor - if there wasn't *some* kind of activity and a closed connection looks like a - read request to the reactor. But when you read from a closed connection you'll - read zero bytes. - - Notice that in the error case or closed case we return -1. That tells the reactor - to call our handle_close() where we'll take care of shutting down cleanly. - - Although we don't make use of them, there are additional parameters you can - use with the recv() call. One of these is an ACE_Time_Value that allows you to - limit the amount of time blocking on the recv(). You would use that if you - weren't sure if data was available. Since we only get to handle_input() when - data is ready, that would be redundant. On the other hand, if you use recv_n() - to read *exactly* a number of bytes then limiting the time you wait for those - bytes might be good. - The other paramter that may come in handy is an integer <i>flags</i>. This is - passed directly to the underlying OS recv() call. See the man page recv(2) - and the header sys/socket.h for the gory details. - */ - switch( this->cli_stream_.recv(buf,sizeof buf) ) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", - this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s",buf)); - } - - return 0; - } - - /* - When handle_input() returns -1, we'll end up here. There are a few housekeeping - chores to handle. - */ - int handle_close (ACE_HANDLE, ACE_Reactor_Mask _mask) - { - /* - Remove ourselves from the reactor. We have to include the DONT_CALL in the - mask so that it won't call handle_close() on us again! - */ - reactor_->remove_handler(this,_mask|ACE_Event_Handler::DONT_CALL); - - /* - Close the socket that we're connected to the client with. - */ - cli_stream_.close(); - - /* - Since we know we were dynamically allocated by the acceptor, now is a good - time to get rid of ourselves. - */ - delete this; - - return 0; - } - -protected: - - /* - Our peer connection. - */ - ACE_SOCK_Stream cli_stream_; - - /* - Our reactor (and our acceptor's reactor). - */ - ACE_Reactor * reactor_; -}; - -#endif /* _CLIENT_HANDLER_H */ - diff --git a/docs/tutorials/001/page01.html b/docs/tutorials/001/page01.html deleted file mode 100644 index 8dba940eba8..00000000000 --- a/docs/tutorials/001/page01.html +++ /dev/null @@ -1,109 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 001</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> - -<P> -<HR WIDTH="100%"></P> - -<P>The purpose of this tutorial is to show you how to create a very simple -server capable of handling multiple client connections. Unlike a "traditional" -server application, this one handles all requests in one process. Issues -of multi-processing and multi-threading will be handled in later tutorial.</P> - -<P> -<HR WIDTH="100%"></P> - -<P>What do you need to create a server?</P> - -<OL> -<LI>Something which accepts connections from clients</LI> - -<LI>Something which handles established connections</LI> - -<LI>A main program loop that handles it all</LI> -</OL> - -<P>The ACE Acceptor provides a solution for our first requirement. -This class is given a TCP/IP port number on which it will listen for -incoming connections. When a connection is attempted, the acceptor will -create a new object (the handler) to deal with the client connection while -the acceptor goes back to listening for other connections.</P> - -<P>The ACE EventHandler solves our second requirement. This doesn't -seem obvious now but as we progress through this tutorial it will become -more clear.</P> - -<P>Finally, a simple <I>main()</I> function will provide our program loop. -After any program initiallization, it will enter an infinite loop which -waits for connection attempts to the Acceptor or data "events" -on the EventHandler.</P> - -<P> -<HR WIDTH="100%"></P> - -<P>Before we continue, I need to introduce one more ACE concept: the Reactor. -</P> - -<P>I don't want to go into great detail at this time on what the Reactor -is, what it does and how it does it but it is necessary for you to understand -the basic function of a reactor because it is going to be in the first -piece of code you see. The figure below depicts the interrelationships -between the Reactor, the Acceptor and the application handler.</P> -<P> <center> <img src="simple.gif" align=center> </center> - -<P>Briefly:<BR> -The reactor is an object which reacts when things happen to other objects. -These things are called <I>events</I>. The <I>other objects</I> are communications -objects which you have <I>registered</I> with the reactor. At the time -of registration, you also specify which events you are interested in. The -reactor is notified by the operating system when the events of interest -occur within the registered objects. The reactor then uses member functions -of the registered object to process the event. Notice that the reactor -doesn't care what happens because of the event. It is the object's responsibility -to process the event correctly. The reactor simply notifies the object -of the event.</P> - -<P>Why use the reactor?</P> - -<P>That will become clear as the tutorial progresses. For now, however, -a brief answer would be this: it allows multiple simultaneous client connections -to be processed efficiently by a single-threaded server. </P> - -<P>Servers have traditionally created a separate thread or process for -each client served. For large-volume services (such as telnet and ftp) -this is appropriate. However, for small-volume services the overhead of -process creation far outweighs the actual work being done. So... folks -begin using threads instead of processes to handle the clients. This is -good also but still, in some cases, the overhead is too much to bear. Instead, -why not have a single thread handle several clients and use a more intelligent -load-balancing methodology than one-thread-or-process-per-client? -<i>Caveat: Handling all requests in one thread of one process is really -only good when the requests can be handled almost instantaneously.</i> -</P> - -<P>This is where the reactor's power and flexibility come into play. The -developer can begin as a simple, single-threaded application that is later -modified to thread-per-client, process-per-client or thread-pool solution. -<P> -If all of this is gibberish & makes you think that ACE is way to hard to -learn, don't worry. We'll go into all the details & explain as we go. -I only went into all of this so that it can kick around in the back of your -mind until you need it later. -<P> -<HR WIDTH="100%"></P> - -<CENTER><P>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>] </P></CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/001/page02.html b/docs/tutorials/001/page02.html deleted file mode 100644 index 87b94c33ab1..00000000000 --- a/docs/tutorials/001/page02.html +++ /dev/null @@ -1,170 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 001</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>From here, I want to move on to the main program loop. In a way, we're -starting at the final product when we do this, but it is a very simple -piece of code and a good place to start. - -<P>The <A HREF="server.cpp">main</A> -program is really quite simple. The real work is done in the ACE derived -classes. - -<P> -Kirthika Parameswaran offers this abstract of Tutorial 1: -<UL> -<P> -This is an simple logging server example. -The Reactor is used to handle more than one client request using a -single thread of execution instead of one thread per client. The Reactor -reactes to events and demultiplexes the events to the appropriate -Event_Handler registered with it, using the "callback" technique. The -reactor runs in an infinte event loop handling all the incoming events. -<P> -The Logging_Acceptor listens at a SERVER PORT address and passively -waits for requests to arrive. The Acceptor is also an Event_Handler and -is registered with the Reactor. This way it is simply yet another -Event_Hanlder for the Reactor and hence no special processing is needed -for it. -<P> -Once a connection request occurs, the Acceptor accepts it and -connection is established. The reactor instance is passed to the -handler so that it can register with the Reactor. It does so with an -ACE_Event_Handler::ACCEPT_MASK. -<P> -The Logging_Client is another Event_Handler which actually handles the -client requests in its handle_input() method. It is also registered -with the Reactor with the ACE_Event_Handler::READ_MASK. -<P> -The Event_Handlers can be unregistered from the Reactor using -handle_close() methods -or explicitly calling the remove_handler() methods. -<P> -This server application builds and executes succesfully waiting for -client requests to arrive. -<P> -</UL> -<HR WIDTH="100%"> -<PRE>/* - Include the header file where our client acceptor is defined. - */ -#include "ace/Reactor.h" - -/* - For simplicity, we create our reactor in the global address space. - In later tutorials we will do something more clever and appropriate. However, - the purpose of this tutorial is to introduce a connection acceptance and - handling, not the full capabilities of a reactor. -*/ -ACE_Reactor * g_reactor; - -/* - Include the header where we define our acceptor object. An acceptor is - an abstraction that allows a server to "accept" connections from clients. -*/ -#include "acceptor.h" - -/* - A TCP/IP server can listen to only one port for connection requests. - Well-known services can always be found at the same address. Lesser-known - services are generally told where to listen by a configuration file or - command-line parameter. For this example, we're satisfied with simply hard-coding - a random but known value. -*/ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int, char **) -{ - /* - Create a Reactor instance. Again, a global pointer isn't exactly the - best way to handle this but for the simple example here, it will be OK. - We'll get cute with it later. - */ - g_reactor = new ACE_Reactor; - - /* - Like the Reactor, I'm skimming over the details of the ADDR - object. What it provides is an abstraction for addressing services in the - network. All we need to know at this point is that we are creating an address - object which specifies the TCP/IP port on which the server - will listen for new connection requests. - */ - ACE_INET_Addr addr (PORT); - - /* - We now create an acceptor object. No connections will - yet be established because the object isn't "open for business" - at this time. Which brings us to the next line... - */ - Logging_Acceptor * peer_acceptor = new Logging_Acceptor(); - - /* - where the acceptor object is opened. You'll find that most ACE - objects have to be open()ed before they're of any use to you. - On this open() call, we're telling the acceptor where to listen - for connections via the 'addr' object. We're also telling it - that we want it to be registered with our 'g_reactor' instance. - */ - if (peer_acceptor->open(addr,g_reactor) == -1 ) - ACE_ERROR_RETURN ((LM_ERROR, "Opening Acceptor\n"), -1); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); - - /* - The reactor's handle_events member function is responsible for looking at - all registered objects and invoking an appropriate member function when - anything of interest occurs. When an event is processed, the handle_events - function returns. In order to get all events, we embed this in an infinite - loop. - - Since we put ourselves into an infinite loop, you'll need to CTRL-C - to exit the program. - */ - while (1) - g_reactor-> handle_events (); - - return 0; -}</PRE> - -<HR WIDTH="100%"> - -<P>As I said, the main program is really quite simple: -<UL> -<LI> -Create an address for the <I>port</I> we want to listen to</LI> - -<LI> -Create an acceptor which listens on that address</LI> - -<LI> -Register the acceptor with a reactor to respond to the connection requests</LI> - -<LI> -Enter an infinite loop to let the reactor handle the events</LI> -</UL> -On the next page, we will take a look at the acceptor and how it responds -to new connection requests. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page01.html">Previous -Page</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/001/page03.html b/docs/tutorials/001/page03.html deleted file mode 100644 index 1b838d61bbd..00000000000 --- a/docs/tutorials/001/page03.html +++ /dev/null @@ -1,217 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 001</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - -<P>Now we begin to look at the <A HREF="acceptor.h">acceptor</A> object. - -<P> -Kirthika has this analogy: -<P> -<UL> -Consider an office: -<P> -Reactor: Receptionist -<P> -Event_Handlers: various Departments catering to specific needs. -<P> -SERVER_PORT: door -<P> -Acceptor: Doorkeeper -<P> -Thus when a needy person (client) enters the open door (port) -maintained by the doorkeeper (acceptor waiting for connection -request), the receptionist(reactor) directs the person towards the -appropriate section (event_handler) which would cater to his needs. -</UL> -<P> -<HR WIDTH="100%"> -<PRE> -#if !defined (_CLIENT_ACCEPTOR_H) -#define _CLIENT_ACCEPTOR_H - -/* - A SOCK_Acceptor knows how to accept socket connections. We'll use - one of those at the heart of our Logging_Acceptor. - */ -#include "ace/SOCK_Acceptor.h" - -/* - An Event_Handler is what you register with ACE_Reactor. When events occur, - the reactor will callback on the Event_Handler. More on that in a few lines. - */ -#include "ace/Event_Handler.h" - -/* - When a client connects, we'll create a Logging_Handler to deal with the - connection. Here, we bring in that declaration. - */ -#include "logger.h" - -/* - Our Logging_Acceptor is derived from ACE_Event_Handler. That lets the - reactor treat our acceptor just like every other handler. - */ -class Logging_Acceptor : public ACE_Event_Handler -{ -public: - - /* - For this simple case we won't bother with either constructor or - destructor. In a real application you would certainly have them. - */ - - /* - Here's the open() method we called from main(). We have two things - to accomplish here: (1) Open the acceptor so that we can hear - client requests and (2) register ourselves with the reactor so that - we can respond to those requests. - */ - int open (const ACE_INET_Addr &_addr, ACE_Reactor * _reactor ) - { - /* - Perform the open() on the acceptor. We pass through the address - at which main() wants us to listen. The second parameter tells - the acceptor it is OK to reuse the address. This is necessary - sometimes to get around closed connections that haven't timed out. - */ - if (this->peer_acceptor_.open (_addr, 1) == -1) - return -1; - - /* - Remember the reactor we're using. We'll need it later when we - create a client connection handler. - */ - reactor_ = _reactor; - - /* - Now we can register with the reactor we were given. Since the reactor - pointer is global, we could have just used that but it's gross enough - already. - Notice that we can pass 'this' right into the registration since we're - derived from ACE_Event_Handler. We also provide ACCEPT_MASK to tell - the reactor that we want to know about accept requests from clients. - */ - return _reactor->register_handler( this, ACE_Event_Handler::ACCEPT_MASK ); - } - -private: - - /* - To provide multi-OS abstraction, ACE uses the concept of "handles" for - connection endpoints. In Unix, this is a traditional file descriptor - (or integer). On other OS's, it may be something else. - The reactor will need to get the handle (file descriptor) to satisfy - it's own internal needs. Our relevant handle is the handle of the - acceptor object, so that's what we provide. - */ - ACE_HANDLE get_handle (void) const - { - return this->peer_acceptor_.get_handle (); - } - - /* - When an accept request arrives, the reactor will invoke the handle_input() - callback. This is where we deal with the connection request. - */ - virtual int handle_input (ACE_HANDLE _handle) - { - /* - The handle provided to us by the reactor is the one that triggered - our up-call. In some advanced situations, you might actually - register a single handler for multiple connections. The _handle - parameter is a way to sort 'em out. Since we don't use that - here, we simply ignore the parameter with the ACE_UNUSED_ARG() macro. - */ - ACE_UNUSED_ARG(_handle); - - /* - In response to the connection request, we create a new Logging_Handler. - This new object will be used to interact with the client until it - disconnects. - */ - Logging_Handler *svc_handler = new Logging_Handler; - - /* - To complete the connection, we invoke the accept() method call on - the acceptor object and provide it with the connection handler instance. - This transfers "ownership" of the connection from the acceptor to the - connection handler. - */ - if (this->peer_acceptor_.accept (*svc_handler) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p", "accept failed"), -1); - - /* - Again, most objects need to be open()ed before they are useful. We'll - give the handler our reactor pointer so that it can register for - events as well. If the open fails, we'll force a close(). - */ - if (svc_handler->open (reactor_) == -1) - svc_handler->close (); - - return 0; - } - -protected: - - /* - Our acceptor object instance - */ - ACE_SOCK_Acceptor peer_acceptor_; - - /* - A place to remember our reactor pointer - */ - ACE_Reactor * reactor_; -}; - -#endif /* _CLIENT_ACCEPTOR_H */ - - -<HR WIDTH="100%"></PRE> -It is important to notice here that we have done very little application-specifc -code in developing this object. In fact, if we take out the progress information, -the only app-specific code is when we create the new <I>Logging_Handler</I> -object to give to the <I>accept</I> function. You may begin to wonder why -there isn't a C++ template that does all of this coding for you. Actually, -the ACE toolkit happens to have one handy: -<UL>typedef ACE_Acceptor <<I>YourHandlerClass</I>, ACE_SOCK_ACCEPTOR> -<I>YourAcceptorClass</I>;</UL> -We would have used it like this: -<UL>typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor;</UL> -This will create a piece of code similar to what I've shown above. The -primary difference is that the <I>handle_input </I>function created by -the template does NOT register the handler with the reactor. In the long-run, -that is good for us because we can then move that logic into the <I>open</I> -function of the <I>Logging_Handler</I> and use a completely-generic acceptor. - -<P>Now that we know how to accept a connection request, let's move on to -the next page where we learn how to handle the actual connection. Even -though we just learned about this cool template thing, we will continue -to use the "hand-written" acceptor developed above. As I mentioned, the -only difference will be in the <I>open</I> function of the connection handler -anyway. - -<P> -<HR WIDTH="100%"> -<CENTER></CENTER> - -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Previous -Page</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/001/page04.html b/docs/tutorials/001/page04.html deleted file mode 100644 index be4742ae2ce..00000000000 --- a/docs/tutorials/001/page04.html +++ /dev/null @@ -1,215 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 001</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Now we begin to look at the <A HREF="logger.h">logger</A> -object. - -<P> -<HR WIDTH="100%"> -<PRE> -#if !defined (_CLIENT_HANDLER_H) -#define _CLIENT_HANDLER_H - -/* - A connection handler will also be derived from ACE_Event_Handler so that we - can register with a reactor. - */ -#include "ace/Event_Handler.h" - -#include "ace/INET_Addr.h" - -/* - Since we're doing TCP/IP, we'll need a SOCK_Stream for the connection. - */ -#include "ace/SOCK_Stream.h" - -class Logging_Handler : public ACE_Event_Handler -{ -public: - - /* - Like the acceptor, we're simple enough to avoid constructor and destructor. - */ - - /* - To open the client handler, we have to register ourselves with the reactor. - Notice that we don't have to "open" our ACE_SOCK_Stream member variable. - Why? Because the call to the acceptor's accept() method took care of those - details for us. - */ - int open ( ACE_Reactor * _reactor ) - { - /* - Remember our reactor... - */ - reactor_ = _reactor; - - /* - In this case we're using the READ_MASK. Like the acceptor, handle_input() - will be called due to this mask but it's a nice piece of bookkeeping to - have separate masks for the separate types of activity. - */ - if (_reactor-> register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - - return 0; - } - - /* - If we're explicitly closed we'll close our "file handle". The net result - is to close the connection to the client and remove ourselves from the - reactor if we're registered - */ - int close (void) - { - return this->handle_close (ACE_INVALID_HANDLE, ACE_Event_Handler::RWE_MASK); - } - - /* - This is a bit of magic... When we call the accept() method of the acceptor - object, it wants to do work on an ACE_SOCK_Stream. We have one of those as - our connection to the client but it would be gross to provide a method to - access that object. It's much cooler if the acceptor can just treat the - Logging_Handler as an ACE_SOCK_Stream. Providing this cast operator lets - that happen cleanly. - */ - operator ACE_SOCK_Stream &() - { - return this->cli_stream_; - } - -protected: - - /* - Again, like the acceptor, we need to provide the connection handle to the reactor. - */ - ACE_HANDLE get_handle (void) const - { - return this->cli_stream_.get_handle (); - } - - /* - And here's the handle_input(). This is really the workhorse of the application. - */ - virtual int handle_input (ACE_HANDLE) - { - /* - Create and initialize a small receive buffer. - */ - char buf[128]; - memset(buf,0,sizeof(buf)); - - /* - Invoke the recv() method of the ACE_SOCK_Stream to get some data. It will - return -1 if there is an error. Otherwise, it will return the number of bytes - read. Of course, if it read zero bytes then the connection must be gone. - How do I know that? Because handle_input() would not be called by the reactor - if there wasn't *some* kind of activity and a closed connection looks like a - read request to the reactor. But when you read from a closed connection you'll - read zero bytes. - - Notice that in the error case or closed case we return -1. That tells the reactor - to call our handle_close() where we'll take care of shutting down cleanly. - - Although we don't make use of them, there are additional parameters you can - use with the recv() call. One of these is an ACE_Time_Value that allows you to - limit the amount of time blocking on the recv(). You would use that if you - weren't sure if data was available. Since we only get to handle_input() when - data is ready, that would be redundant. On the other hand, if you use recv_n() - to read *exactly* a number of bytes then limiting the time you wait for those - bytes might be good. - The other paramter that may come in handy is an integer <i>flags</i>. This is - passed directly to the underlying OS recv() call. See the man page recv(2) - and the header sys/socket.h for the gory details. - */ - switch( this->cli_stream_.recv(buf,sizeof buf) ) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", - this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s",buf)); - } - - return 0; - } - - /* - When handle_input() returns -1, we'll end up here. There are a few housekeeping - chores to handle. - */ - int handle_close (ACE_HANDLE, ACE_Reactor_Mask _mask) - { - /* - Remove ourselves from the reactor. We have to include the DONT_CALL in the - mask so that it won't call handle_close() on us again! - */ - reactor_->remove_handler(this,_mask|ACE_Event_Handler::DONT_CALL); - - /* - Close the socket that we're connected to the client with. - */ - cli_stream_.close(); - - /* - Since we know we were dynamically allocated by the acceptor, now is a good - time to get rid of ourselves. - */ - delete this; - - return 0; - } - -protected: - - /* - Our peer connection. - */ - ACE_SOCK_Stream cli_stream_; - - /* - Our reactor (and our acceptor's reactor). - */ - ACE_Reactor * reactor_; -}; - -#endif /* _CLIENT_HANDLER_H */</PRE> - - -<P> -<HR WIDTH="100%"> - -<P> -The comments really should tell the story. The really -interesting stuff is in <i>handle_input()</i>. Everything -else is just housekeeping. -In the future, we'll learn about ACE_Svc_Handler<> -which will take care of most of the housekeeping for us. -<P> -<HR WIDTH="100%"> -<CENTER></CENTER> - -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page03.html">Previous -Page</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/001/page05.html b/docs/tutorials/001/page05.html deleted file mode 100644 index b242b31406c..00000000000 --- a/docs/tutorials/001/page05.html +++ /dev/null @@ -1,68 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 001</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>This concludes the first tutorial on using ACE. We've learned how to -create a simple server without knowing very much about network programming. - -<P>The code used in this tutorial is for illustration purposes. That means -it may or may not work. Actually, it <I>does</I> work but the -astute reader will notice a number of places for potential memory leaks. -We'll work on cleaning those up in future tutorials but if you find one -feel free to send me a fix & I'll integrate it into the tutorial. - -<P>You can download all of the <A HREF="Source.tgz">source</A> -or individual files: -<UL> -<LI> -<A HREF="00SetEnv">Environment -Settings</A></LI> - -<LI> -<A HREF="Makefile">Makefile</A></LI> - -<LI> -<A HREF="server.cpp">main -program</A></LI> - -<LI> -<A HREF="acceptor.h">acceptor -object</A></LI> - -<LI> -<A HREF="logger.h">connection -handler</A></LI> -</UL> -(The source is a gzip'ed tar file which can be unpacked using <I>winzip</I> -or the Unix command <I>tar -xvzf filename</I>.) - -<P> -To read more about the patterns used in this example (as well as -quite a few which aren't!), you should check out -<A HREF="http://www.cs.wustl.edu/~schmidt/patterns-ace.html">http://www.cs.wustl.edu/~schmidt/patterns-ace.html.</A> -In fact, it's probably safe to say that the concepts found there will keep -coming back to haunt you as these tutorials continue. -<P> -<HR WIDTH="100%"> -<CENTER></CENTER> - -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page04.html">Previous -Page</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/001/server.cpp b/docs/tutorials/001/server.cpp deleted file mode 100644 index 412f43a9a34..00000000000 --- a/docs/tutorials/001/server.cpp +++ /dev/null @@ -1,85 +0,0 @@ - -// $Id$ - - -/* - Include the header file where our client acceptor is defined. - */ -#include "ace/Reactor.h" - -/* - For simplicity, we create our reactor in the global address space. - In later tutorials we will do something more clever and appropriate. However, - the purpose of this tutorial is to introduce a connection acceptance and - handling, not the full capabilities of a reactor. -*/ -ACE_Reactor * g_reactor; - -/* - Include the header where we define our acceptor object. An acceptor is - an abstraction that allows a server to "accept" connections from clients. -*/ -#include "acceptor.h" - -/* - A TCP/IP server can listen to only one port for connection requests. - Well-known services can always be found at the same address. Lesser-known - services are generally told where to listen by a configuration file or - command-line parameter. For this example, we're satisfied with simply hard-coding - a random but known value. -*/ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int, char *[]) -{ - /* - Create a Reactor instance. Again, a global pointer isn't exactly the - best way to handle this but for the simple example here, it will be OK. - We'll get cute with it later. - */ - g_reactor = new ACE_Reactor; - - /* - Like the Reactor, I'm skimming over the details of the ADDR - object. What it provides is an abstraction for addressing services in the - network. All we need to know at this point is that we are creating an address - object which specifies the TCP/IP port on which the server - will listen for new connection requests. - */ - ACE_INET_Addr addr (PORT); - - /* - We now create an acceptor object. No connections will - yet be established because the object isn't "open for business" - at this time. Which brings us to the next line... - */ - Logging_Acceptor * peer_acceptor = new Logging_Acceptor(); - - /* - where the acceptor object is opened. You'll find that most ACE - objects have to be open()ed before they're of any use to you. - On this open() call, we're telling the acceptor where to listen - for connections via the 'addr' object. We're also telling it - that we want it to be registered with our 'g_reactor' instance. - */ - if (peer_acceptor->open(addr,g_reactor) == -1 ) - ACE_ERROR_RETURN ((LM_ERROR, "Opening Acceptor\n"), -1); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); - - /* - The reactor's handle_events member function is responsible for looking at - all registered objects and invoking an appropriate member function when - anything of interest occurs. When an event is processed, the handle_events - function returns. In order to get all events, we embed this in an infinite - loop. - - Since we put ourselves into an infinite loop, you'll need to CTRL-C - to exit the program. - */ - while (1) - g_reactor-> handle_events (); - - return 0; -} - diff --git a/docs/tutorials/001/simple.fig b/docs/tutorials/001/simple.fig deleted file mode 100644 index afea1bddabe..00000000000 --- a/docs/tutorials/001/simple.fig +++ /dev/null @@ -1,57 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 7800 5925 11850 6900 -2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5 - 11850 6900 11850 5925 7800 5925 7800 6900 11850 6900 -4 0 0 0 0 0 12 0.0000 4 180 3360 7800 6150 Application_Handler (ACE_Event_Handler)\001 -4 0 0 0 0 0 12 0.0000 4 180 3825 7950 6450 handle_input() {read connection, process data ... }\001 -4 0 0 0 0 0 12 0.0000 4 180 1335 7950 6675 get_handle() {...}\001 --6 -2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5 - 5100 7200 5100 5925 1725 5925 1725 7200 5100 7200 -2 1 1 1 1 7 0 0 -1 4.000 0 0 -1 1 0 2 - 2 1 1.00 60.00 120.00 - 4950 6600 7725 6600 -2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 0 1 2 - 2 1 1.00 60.00 120.00 - 3900 5925 5400 2250 -2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 0 1 2 - 2 1 1.00 60.00 120.00 - 8400 5925 6600 2250 -2 1 0 1 12 7 0 0 -1 0.000 0 0 -1 1 0 2 - 2 1 1.00 60.00 120.00 - 4500 5925 6000 2250 -2 1 0 1 12 7 0 0 -1 0.000 0 0 -1 1 0 2 - 2 1 1.00 60.00 120.00 - 9000 5925 7200 2250 -2 1 2 2 24 7 0 0 -1 3.000 0 0 -1 0 1 2 - 0 0 1.00 60.00 120.00 - 3300 7200 3300 8325 -2 1 0 2 15 7 0 0 -1 0.000 0 0 -1 1 1 2 - 0 0 1.00 60.00 120.00 - 0 0 1.00 60.00 120.00 - 9600 6900 9600 8025 -2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5 - 7500 2250 7500 1425 5100 1425 5100 2250 7500 2250 -4 0 0 0 0 0 12 0.0000 4 180 3045 1800 6150 Client_Acceptor (ACE_Event_Handler)\001 -4 0 0 0 0 0 12 0.0000 4 180 2565 1950 6450 handle_input() {open data conn ...\001 -4 0 0 0 0 0 12 0.0000 4 180 1755 3150 6675 create Handler Obj ... }\001 -4 0 0 0 0 0 12 0.0000 4 180 1335 1950 6900 get_handle() {...}\001 -4 0 1 0 0 0 12 0.0000 4 180 1800 5550 6450 create new Handler Obj\001 -4 0 24 0 0 0 12 0.0000 4 180 1530 2550 7800 Connection Request\001 -4 0 15 0 0 0 12 0.0000 4 135 1275 9000 7500 Data Connection\001 -4 0 0 0 0 0 12 0.0000 4 135 600 5925 1725 Reactor\001 -4 0 0 0 0 0 12 0.0000 4 180 1935 5325 2025 event handler dispatching\001 -4 0 0 0 0 0 12 0.0000 4 180 585 8175 4875 register\001 -4 0 0 0 0 0 12 0.0000 4 180 585 4650 5025 register\001 -4 0 0 0 0 0 12 0.0000 4 180 1110 4200 3675 handle_input()\001 -4 0 0 0 0 0 12 0.0000 4 180 975 4200 3900 get_handle()\001 -4 0 0 0 0 0 12 0.0000 4 180 1110 6675 3675 handle_input()\001 -4 0 0 0 0 0 12 0.0000 4 180 975 6675 3900 get_handle()\001 diff --git a/docs/tutorials/001/simple.gif b/docs/tutorials/001/simple.gif Binary files differdeleted file mode 100644 index ef29d88a120..00000000000 --- a/docs/tutorials/001/simple.gif +++ /dev/null diff --git a/docs/tutorials/002/002.dsp b/docs/tutorials/002/002.dsp deleted file mode 100644 index 2632dc42e5f..00000000000 --- a/docs/tutorials/002/002.dsp +++ /dev/null @@ -1,104 +0,0 @@ -# Microsoft Developer Studio Project File - Name="002" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=002 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "002.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "002.mak" CFG="002 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "002 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "002 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "002 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "002 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "002 - Win32 Release"
-# Name "002 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\handler.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/002/00SetEnv b/docs/tutorials/002/00SetEnv deleted file mode 100644 index eca78e10c85..00000000000 --- a/docs/tutorials/002/00SetEnv +++ /dev/null @@ -1,2 +0,0 @@ -export ACE_ROOT=/local/src/ACE/ACE_wrappers -export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH diff --git a/docs/tutorials/002/Makefile b/docs/tutorials/002/Makefile deleted file mode 100644 index d590e57dac8..00000000000 --- a/docs/tutorials/002/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for the Reactor version of the Server Logging Daemon -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server - -VLDLIBS = $(LDLIBS:%=%$(VAR)) - -BUILD = $(VBIN) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -# DO NOT DELETE THIS LINE -- g++dep uses it. -# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. - - - -# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/docs/tutorials/002/handler.h b/docs/tutorials/002/handler.h deleted file mode 100644 index 9e8a9e7ce62..00000000000 --- a/docs/tutorials/002/handler.h +++ /dev/null @@ -1,166 +0,0 @@ - -// $Id$ - -#ifndef LOGGING_HANDLER_H -#define LOGGING_HANDLER_H - -#include "ace/INET_Addr.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" -#include "ace/Reactor.h" - -/* - Since we used the template to create the acceptor, we don't know if there is a - way to get to the reactor it uses. We'll take the easy way out and grab the - global pointer. (There is a way to get back to the acceptor's reactor that - we'll see later on.) - */ -extern ACE_Reactor * g_reactor; - -/* - This time we're deriving from ACE_Svc_Handler instead of ACE_Event_Handler. - The big reason for this is because it already knows how to contain a SOCK_Stream - and provides all of the method calls needed by the reactor. The second template - parameter is for some advanced stuff we'll do with later servers. For now, just - use it as is... - */ -class Logging_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ - -public: - - /* - The Acceptor<> template will open() us when there is a new client connection. - */ - virtual int open (void *) - { - ACE_INET_Addr addr; - - /* - Ask the peer() (held in our baseclass) to tell us the address of the cient - which has connected. There may be valid reasons for this to fail where we - wouldn't want to drop the connection but I can't think of one. - */ - if (this->peer ().get_remote_addr (addr) == -1) - return -1; - - /* - The Acceptor<> won't register us with it's reactor, so we have to do so - ourselves. This is where we have to grab that global pointer. Notice - that we again use the READ_MASK so that handle_input() will be called - when the client does something. - */ - if (g_reactor->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - - /* - Here's another new treat. We schedule a timer event. This particular one - will fire in two seconds and then every three seconds after that. It doesn't - serve any useful purpose in our application other than to show you how it - is done. - */ - else if (g_reactor->schedule_timer (this, 0, ACE_Time_Value (2), ACE_Time_Value (3)) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t register with reactor\n"), -1); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name() )); - - return 0; - } - - /* - This is a matter of style & maybe taste. Instead of putting all of this stuff - into a destructor, we put it here and request that everyone call destroy() - instead of 'delete'. - */ - virtual void destroy (void) - { - /* - Remove ourselves from the reactor - */ - g_reactor->remove_handler(this,ACE_Event_Handler::READ_MASK|ACE_Event_Handler::DONT_CALL); - - /* - Cancel that timer we scheduled in open() - */ - g_reactor->cancel_timer (this); - - /* - Shut down the connection to the client. - */ - this->peer ().close (); - - /* - Free our memory. - */ - delete this; - } - - /* - If somebody doesn't like us, the will close() us. Actually, if our open() method - returns -1, the Acceptor<> will invoke close() on us for cleanup. - */ - virtual int close (u_long _flags = 0) - { - /* - The ACE_Svc_Handler baseclass requires the _flags parameter. We don't - use it here though, so we mark it as UNUSED. You can accomplish the - same thing with a signature like handle_input's below. - */ - ACE_UNUSED_ARG(_flags); - - /* - Clean up and go away. - */ - this->destroy (); - return 0; - } - -protected: - - /* - Respond to input just like Tutorial 1. - */ - virtual int handle_input (ACE_HANDLE) - { - char buf[128]; - memset (buf, 0, sizeof (buf)); - - switch (this->peer ().recv (buf, sizeof buf)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", buf)); - } - - return 0; - } - - /* - When the timer expires, handle_timeout() will be called. The 'arg' is the value passed - after 'this' in the schedule_timer() call. You can pass in anything there that you can - cast to a void*. - */ - virtual int handle_timeout (const ACE_Time_Value & tv, const void *arg) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling timeout from this = %u\n", this)); - return 0; - } - - /* - Clean ourselves up when handle_input() (or handle_timer()) returns -1 - */ - virtual int handle_close(ACE_HANDLE, ACE_Reactor_Mask _mask) - { - this->destroy(); - return 0; - } -}; - -#endif // LOGGING_HANDLER_H diff --git a/docs/tutorials/002/page01.html b/docs/tutorials/002/page01.html deleted file mode 100644 index 6b30588b567..00000000000 --- a/docs/tutorials/002/page01.html +++ /dev/null @@ -1,57 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 002</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 002<BR> -Creating a Better Server </FONT></B></P></CENTER> - -<P> -<HR WIDTH="100%"></P> - -<P>In this tutorial, we will build a little on what we learned in the first -tutorial and add a few extras. In the end, we will have a better server -object that is actually simpler and more maintainable than the one we created -before.</P> - -<P> -<HR WIDTH="100%"></P> - -<P>To begin, let's ask ourselves the same thing we did at the beginning -of tutorial 001:</P> - -<UL> -<P>What do you need to create a server?</P> -</UL> - -<OL> -<OL> -<LI>Something which accepts connections from clients</LI> - -<LI>Something which handles established connections</LI> - -<LI>A main program loop that handles it all</LI> -</OL> -</OL> - -<P>Previously, we created a solution which addressed each one of these -questions specifically. At the end of it all, we realized that our only -application-specific coding was confined to the <I>handler</I> portion -of the program. We hinted that there may be a way to eliminate hand-coding -an <I>acceptor</I> each time we want to create a server. Here, we will -explore that approach.</P> - -<P> -<HR WIDTH="100%"></P> - -<CENTER><P>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>] </P></CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/002/page02.html b/docs/tutorials/002/page02.html deleted file mode 100644 index 2c167a2a5cd..00000000000 --- a/docs/tutorials/002/page02.html +++ /dev/null @@ -1,162 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 002</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 002</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a Better Server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Like Tutorial 1, this is also a rather small program. I'm going -to add a couple of new ideas along the way but to make up for it I'm also -going to simplify the acceptor a great deal. - -<P> -Kirthika's Abstract: -<UL> -This is a server example made simpler due to the use of off-the-shelf -components and classes from ACE. -<P> -Here, the Logging_Acceptor is an ACE_Acceptor class which is associated -with the Logging_Handler and the ACE_SOCK_ACCEPTOR. This will now -accept connection requests from the clients on being opened with the -reactor instance passed to it. -<P> -We also implement a signal to capture CTRL-C [ which generates SIGINT ] using ACE_SigAction and -ACE_SignalHandler. This signal can now be used to stop the reactor -from handling events. -<P> -Then, the reactor is allowed to loop infintely until it is shut down -using a ^C, after which both the reactor as well as the acceptor are -destroyed. -<P> -The Logging_Handler derives from the ACE_Svc_Handler instead of the -Event_Handler since the Svc_Handler has inbuilt SOCK_Stream and -provides all the calls needed by the reactor. The Svc_Handler has the -ability to react to events and communicate to remote tasks using the -underlying data stream passed to it. -<P> -A timer is scheduled in the reactor which does nothing but simply -display how it could be used to provide periodic processing when -needed. The ACE_TimeValue is used to set the time period. -<P> -Also, optimisations have been made in the form of a separate function -for -destroying the objects used. -<P> -Thus a simpler server has now been built which successfully -demonstrates how simple a task, writing a server can become on using -the various ACE components judiciously. -</UL> -<P>We begin by looking at the <A HREF="server.cpp">main (server.cpp)</A> portion program: - -<P> -<HR WIDTH="100%"> -<PRE> -/* - As before, we need a few ACE objects as well as our Logging_Handler declaration. - */ -#include "ace/Acceptor.h" -#include "ace/SOCK_Acceptor.h" -#include "ace/Reactor.h" -#include "handler.h" - -/* - We'll still use the global reactor pointer. There's a snappy way around this - that shows up in later server tutorials. - */ -ACE_Reactor * g_reactor; - -/* - This was hinted at in Tutorial 1. Remember the hand-coded acceptor that we - created there? This template does all of that and more and better. If you - find yourself creating code that doesn't feel like a part of your application, - there's a good chance that ACE has a template or framework component to do - it for you. - */ -typedef ACE_Acceptor < Logging_Handler, ACE_SOCK_ACCEPTOR > Logging_Acceptor; - -/* - One of the new things will be a signal handler so that we can exit the application - somewhat cleanly. The 'finished' flag is used instead of the previous infninite - loop and the 'handler' will set that flag in respose to SIGINT (CTRL-C). - */ -static sig_atomic_t finished = 0; -extern "C" void handler (int) -{ - finished = 1; -} - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int, char **) -{ - // Create the reactor we'll register our event handler derivatives with. - g_reactor = new ACE_Reactor; - - // Create the acceptor that will listen for client connetions - Logging_Acceptor peer_acceptor; - - /* - Notice how similar this is to the open() call in Tutorial 1. I read - ahead when I created that one so that it would come out this way... - */ - if (peer_acceptor.open (ACE_INET_Addr (PORT), g_reactor) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - - /* - Here's the easiest way to respond to signals in your application. Simply - construct an ACE_Sig_Action object with a "C" function and the signal you - want to capture. As you might expect, there is also a way to register - signal handlers with a reactor but we take the easy-out here. - */ - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); - - // Perform logging service until the signal handler receives SIGINT. - while (!finished) - g_reactor->handle_events (); - - // Close the acceptor so that no more clients will be taken in. - peer_acceptor.close(); - - // Free up the memory allocated for the reactor. - delete g_reactor; - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); - - return 0; -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - -</PRE> - - -<P> -<HR WIDTH="100%"> -<CENTER></CENTER> - -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page01.html">Previous -Page</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/002/page03.html b/docs/tutorials/002/page03.html deleted file mode 100644 index 4fd57e01614..00000000000 --- a/docs/tutorials/002/page03.html +++ /dev/null @@ -1,190 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 002</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 002</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a Better Server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Now lets take a look at the new <A HREF="handler.h">Logging_Handler</A>: - -<P> -<HR WIDTH="100%"> -<BR> -<PRE>#ifndef LOGGING_HANDLER_H -#define LOGGING_HANDLER_H - -/* - Since we used the template to create the acceptor, we don't know if there is a - way to get to the reactor it uses. We'll take the easy way out and grab the - global pointer. (There is a way to get back to the acceptor's reactor that - we'll see later on.) - */ -extern ACE_Reactor * g_reactor; - -/* - This time we're deriving from ACE_Svc_Handler instead of ACE_Event_Handler. - The big reason for this is because it already knows how to contain a SOCK_Stream - and provides all of the method calls needed by the reactor. The second template - parameter is for some advanced stuff we'll do with later servers. For now, just - use it as is... - */ -class Logging_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ - -public: - - /* - The Acceptor<> template will open() us when there is a new client connection. - */ - int open (void *) - { - ACE_INET_Addr addr; - - /* - Ask the peer() (held in our baseclass) to tell us the address of the cient - which has connected. There may be valid reasons for this to fail where we - wouldn't want to drop the connection but I can't think of one. - */ - if (this->peer ().get_remote_addr (addr) == -1) - return -1; - - /* - The Acceptor<> won't register us with it's reactor, so we have to do so - ourselves. This is where we have to grab that global pointer. Notice - that we again use the READ_MASK so that handle_input() will be called - when the client does something. - */ - if (g_reactor->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - - /* - Here's another new treat. We schedule a timer event. This particular one - will fire in two seconds and then every three seconds after that. It doesn't - serve any useful purpose in our application other than to show you how it - is done. - */ - else if (g_reactor->schedule_timer (this, 0, ACE_Time_Value (2), ACE_Time_Value (3)) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t register with reactor\n"), -1); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name() )); - - return 0; - } - - /* - This is a matter of style & maybe taste. Instead of putting all of this stuff - into a destructor, we put it here and request that everyone call destroy() - instead of 'delete'. - */ - void destroy (void) - { - /* - Remove ourselves from the reactor - */ - g_reactor->remove_handler(this,ACE_Event_Handler::READ_MASK|ACE_Event_Handler::DONT_CALL); - - /* - Cancel that timer we scheduled in open() - */ - g_reactor->cancel_timer (this); - - /* - Shut down the connection to the client. - */ - this->peer ().close (); - - /* - Free our memory. - */ - delete this; - } - - /* - If somebody doesn't like us, the will close() us. Actually, if our open() method - returns -1, the Acceptor<> will invoke close() on us for cleanup. - */ - virtual int close (u_long _flags = 0) - { - /* - The ACE_Svc_Handler baseclass requires the _flags parameter. We don't - use it here though, so we mark it as UNUSED. You can accomplish the - same thing with a signature like handle_input's below. - */ - ACE_UNUSED_ARG(_flags); - - /* - Clean up and go away. - */ - this->destroy (); - return 0; - } - -protected: - - /* - Respond to input just like Tutorial 1. - */ - int handle_input (ACE_HANDLE) - { - char buf[128]; - memset (buf, 0, sizeof (buf)); - - switch (this->peer ().recv (buf, sizeof buf)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", buf)); - } - - return 0; - } - - /* - When the timer expires, handle_timeout() will be called. The 'arg' is the value passed - after 'this' in the schedule_timer() call. You can pass in anything there that you can - cast to a void*. - */ - int handle_timeout (const ACE_Time_Value & tv, const void *arg) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling timeout from this = %u\n", this)); - return 0; - } - - /* - Clean ourselves up when handle_input() (or handle_timer()) returns -1 - */ - int handle_close(ACE_HANDLE, ACE_Reactor_Mask _mask) - { - this->destroy(); - return 0; - } -}; - -#endif // LOGGING_HANDLER_H</PRE> - - -<P> -<HR WIDTH="100%"> -<CENTER></CENTER> - -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Previous -Page</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/002/page04.html b/docs/tutorials/002/page04.html deleted file mode 100644 index 14837122aca..00000000000 --- a/docs/tutorials/002/page04.html +++ /dev/null @@ -1,41 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 002</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 002</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a Better Server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Well, that's it for the second tutorial. We've found a much easier way -to create a server, especially the acceptor part. At the same time, we -introduced more functionality and robustness. Not bad for a day's work. -<BR> -<UL> -<LI> -<A HREF="00SetEnv">Environment -Settings</A></LI> - -<LI> -<A HREF="Makefile">Makefile</A></LI> - -<LI> -<A HREF="server.cpp">server.cpp</A></LI> -</UL> - -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page03.html">Previous -Page</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/002/server.cpp b/docs/tutorials/002/server.cpp deleted file mode 100644 index bca90aa01bc..00000000000 --- a/docs/tutorials/002/server.cpp +++ /dev/null @@ -1,89 +0,0 @@ - -// $Id$ - - -/* - As before, we need a few ACE objects as well as our Logging_Handler declaration. - */ -#include "ace/Acceptor.h" -#include "ace/SOCK_Acceptor.h" -#include "ace/Reactor.h" -#include "handler.h" - -/* - We'll still use the global reactor pointer. There's a snappy way around this - that shows up in later server tutorials. - */ -ACE_Reactor * g_reactor; - -/* - This was hinted at in Tutorial 1. Remember the hand-coded acceptor that we - created there? This template does all of that and more and better. If you - find yourself creating code that doesn't feel like a part of your application, - there's a good chance that ACE has a template or framework component to do - it for you. - */ -typedef ACE_Acceptor < Logging_Handler, ACE_SOCK_ACCEPTOR > Logging_Acceptor; - -/* - One of the new things will be a signal handler so that we can exit the application - somewhat cleanly. The 'finished' flag is used instead of the previous infninite - loop and the 'handler' will set that flag in respose to SIGINT (CTRL-C). - */ -static sig_atomic_t finished = 0; -extern "C" void handler (int) -{ - finished = 1; -} - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int, char **) -{ - // Create the reactor we'll register our event handler derivatives with. - g_reactor = new ACE_Reactor; - - // Create the acceptor that will listen for client connetions - Logging_Acceptor peer_acceptor; - - /* - Notice how similar this is to the open() call in Tutorial 1. I read - ahead when I created that one so that it would come out this way... - */ - if (peer_acceptor.open (ACE_INET_Addr (PORT), g_reactor) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - - /* - Here's the easiest way to respond to signals in your application. Simply - construct an ACE_Sig_Action object with a "C" function and the signal you - want to capture. As you might expect, there is also a way to register - signal handlers with a reactor but we take the easy-out here. - */ - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); - - // Perform logging service until the signal handler receives SIGINT. - while (!finished) - g_reactor->handle_events (); - - // Close the acceptor so that no more clients will be taken in. - peer_acceptor.close(); - - // Free up the memory allocated for the reactor. - delete g_reactor; - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); - - return 0; -} - - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - diff --git a/docs/tutorials/003/003.dsp b/docs/tutorials/003/003.dsp deleted file mode 100644 index c4a5a21faa4..00000000000 --- a/docs/tutorials/003/003.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# Microsoft Developer Studio Project File - Name="003" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=003 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "003.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "003.mak" CFG="003 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "003 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "003 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "003 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "003 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "003 - Win32 Release"
-# Name "003 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/003/00SetEnv b/docs/tutorials/003/00SetEnv deleted file mode 100644 index eca78e10c85..00000000000 --- a/docs/tutorials/003/00SetEnv +++ /dev/null @@ -1,2 +0,0 @@ -export ACE_ROOT=/local/src/ACE/ACE_wrappers -export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH diff --git a/docs/tutorials/003/Makefile b/docs/tutorials/003/Makefile deleted file mode 100644 index c5da941f1b7..00000000000 --- a/docs/tutorials/003/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for client logging applications -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client - -LSRC = $(addsuffix .cpp,$(BIN)) - -VLDLIBS = $(LDLIBS:%=%$(VAR)) - -BUILD = $(VBIN) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - diff --git a/docs/tutorials/003/client.cpp b/docs/tutorials/003/client.cpp deleted file mode 100644 index 29bb77d2ce3..00000000000 --- a/docs/tutorials/003/client.cpp +++ /dev/null @@ -1,111 +0,0 @@ - -// $Id$ - -/* - To establish a socket connection to a server, we'll need an ACE_SOCK_Connector. - */ -#include "ace/SOCK_Connector.h" - -/* - Unlike the previous two Tutorials, we're going to allow the user to provide - command line options this time. Still, we need defaults in case that isn't - done. - */ -static u_short SERVER_PORT = ACE_DEFAULT_SERVER_PORT; -static const char *const SERVER_HOST = ACE_DEFAULT_SERVER_HOST; -static const int MAX_ITERATIONS = 4; - -int main (int argc, char *argv[]) -{ - /* - Accept the users's choice of hosts or use the default. Then do the same - for the TCP/IP port at which the server is listening as well as the - number of iterations to perform. - */ - const char *server_host = argc > 1 ? argv[1] : SERVER_HOST; - u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : SERVER_PORT; - int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : MAX_ITERATIONS; - - /* - Build ourselves a Stream socket. This is a connected socket that provides - reliable end-to-end communications. We will use the server object to send - data to the server we connect to. - */ - ACE_SOCK_Stream server; - - /* - And we need a connector object to establish that connection. The ACE_SOCK_Connector - object provides all of the tools we need to establish a connection once we know the - server's network address... - */ - ACE_SOCK_Connector connector; - - /* - Which we create with an ACE_INET_Addr object. This object is given the TCP/IP port - and hostname of the server we want to connect to. - */ - ACE_INET_Addr addr (server_port, server_host); - - /* - So, we feed the Addr object and the Stream object to the connector's connect() member - function. Given this information, it will establish the network connection to the - server and attacht that connection to the server object. - */ - if (connector.connect (server, addr) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - /* - Just for grins, we'll send the server several messages. - */ - for (int i = 0; i < max_iterations; i++) - { - char buf[BUFSIZ]; - - /* - Create our message with the message number - */ - ACE_OS::sprintf (buf, "message = %d\n", i + 1); - - /* - Send the message to the server. We use the server object's send_n() function to - send all of the data at once. There is also a send() function but it may not send - all of the data. That is due to network buffer availability and such. If the send() - doesn't send all of the data, it is up to you to program things such that it will - keep trying until all of the data is sent or simply give up. The send_n() function - already does the "keep tyring" option for us, so we use it. - - Like the send() method used in the servers we've seen, there are two additional - parameters you can use on the send() and send_n() method calls. The timeout - parameter limits the amount of time the system will attempt to send the data - to the peer. The flags parameter is passed directly to the OS send() system - call. See send(2) for the valid flags values. - */ - if (server.send_n ( buf, strlen(buf) ) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); - } - else - { - /* - Pause for a second. - */ - ACE_OS::sleep (1); - } - } - - /* - Close the connection to the server. The servers we've created so far all are based - on the ACE_Reactor. When we close(), the server's reactor will see activity for - the registered event handler and invoke handle_input(). That, in turn, will try - to read from the socket but get back zero bytes. At that point, the server will know - that we've closed from our side. - */ - if (server.close () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); - } - - return 0; -} diff --git a/docs/tutorials/003/page01.html b/docs/tutorials/003/page01.html deleted file mode 100644 index 075fc2888e4..00000000000 --- a/docs/tutorials/003/page01.html +++ /dev/null @@ -1,152 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 003</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 003</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a Simple Client</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Now that we've seen how to create servers, let's spend just a moment -making a client. Since this is so easy, I'm going to do all of it in this -one page. - -<P> -<HR WIDTH="100%"> -<PRE>/* - To establish a socket connection to a server, we'll need an ACE_SOCK_Connector. - */ -#include "ace/SOCK_Connector.h" - -/* - Unlike the previous two Tutorials, we're going to allow the user to provide - command line options this time. Still, we need defaults in case that isn't - done. - */ -static u_short SERVER_PORT = ACE_DEFAULT_SERVER_PORT; -static const char *const SERVER_HOST = ACE_DEFAULT_SERVER_HOST; -static const int MAX_ITERATIONS = 4; - -int main (int argc, char *argv[]) -{ - /* - Accept the users's choice of hosts or use the default. Then do the same - for the TCP/IP port at which the server is listening as well as the - number of iterations to perform. - */ - const char *server_host = argc > 1 ? argv[1] : SERVER_HOST; - u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : SERVER_PORT; - int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : MAX_ITERATIONS; - - /* - Build ourselves a Stream socket. This is a connected socket that provides - reliable end-to-end communications. We will use the server object to send - data to the server we connect to. - */ - ACE_SOCK_Stream server; - - /* - And we need a connector object to establish that connection. The ACE_SOCK_Connector - object provides all of the tools we need to establish a connection once we know the - server's network address... - */ - ACE_SOCK_Connector connector; - - /* - Which we create with an ACE_INET_Addr object. This object is given the TCP/IP port - and hostname of the server we want to connect to. - */ - ACE_INET_Addr addr (server_port, server_host); - - /* - So, we feed the Addr object and the Stream object to the connector's connect() member - function. Given this information, it will establish the network connection to the - server and attacht that connection to the server object. - */ - if (connector.connect (server, addr) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - /* - Just for grins, we'll send the server several messages. - */ - for (int i = 0; i < max_iterations; i++) - { - char buf[BUFSIZ]; - - /* - Create our message with the message number - */ - ACE_OS::sprintf (buf, "message = %d\n", i + 1); - - /* - Send the message to the server. We use the server object's send_n() function to - send all of the data at once. There is also a send() function but it may not send - all of the data. That is due to network buffer availability and such. If the send() - doesn't send all of the data, it is up to you to program things such that it will - keep trying until all of the data is sent or simply give up. The send_n() function - already does the "keep tyring" option for us, so we use it. - - Like the send() method used in the servers we've seen, there are two additional - parameters you can use on the send() and send_n() method calls. The timeout - parameter limits the amount of time the system will attempt to send the data - to the peer. The flags parameter is passed directly to the OS send() system - call. See send(2) for the valid flags values. - */ - if (server.send_n ( buf, strlen(buf) ) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); - } - else - { - /* - Pause for a second. - */ - ACE_OS::sleep (1); - } - } - - /* - Close the connection to the server. The servers we've created so far all are based - on the ACE_Reactor. When we close(), the server's reactor will see activity for - the registered event handler and invoke handle_input(). That, in turn, will try - to read from the socket but get back zero bytes. At that point, the server will know - that we've closed from our side. - */ - if (server.close () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); - } - - return 0; -}</PRE> - -<HR WIDTH="100%"> - -<P>Ok, so that was pretty easy. What would be even easier would be to wrap -all of the connection mess up in an object and overload a couple of basic -operators to make things less network-centric. Perhaps we'll see that in -another tutorial. - -<P>If you want to compile it yourself, here's the <A HREF="client.cpp">source</A>, -the <A HREF="Makefile">Makefile</A>, -and <A HREF="00SetEnv">Environment -settings</A>. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/004/004.dsp b/docs/tutorials/004/004.dsp deleted file mode 100644 index 67106a5bf88..00000000000 --- a/docs/tutorials/004/004.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# Microsoft Developer Studio Project File - Name="004" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=004 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "004.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "004.mak" CFG="004 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "004 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "004 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "004 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "004 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "004 - Win32 Release"
-# Name "004 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/004/00SetEnv b/docs/tutorials/004/00SetEnv deleted file mode 100644 index eca78e10c85..00000000000 --- a/docs/tutorials/004/00SetEnv +++ /dev/null @@ -1,2 +0,0 @@ -export ACE_ROOT=/local/src/ACE/ACE_wrappers -export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH diff --git a/docs/tutorials/004/Makefile b/docs/tutorials/004/Makefile deleted file mode 100644 index 06940b7f6c4..00000000000 --- a/docs/tutorials/004/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for client logging applications -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client - -LSRC = $(addsuffix .cpp,$(BIN)) - -VLDLIBS = $(LDLIBS:%=%$(VAR)) - -BUILD = $(VBIN) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - diff --git a/docs/tutorials/004/client.cpp b/docs/tutorials/004/client.cpp deleted file mode 100644 index 90a40fafb79..00000000000 --- a/docs/tutorials/004/client.cpp +++ /dev/null @@ -1,264 +0,0 @@ - -// $Id$ - -/* - We need the connector object & we also bring in a simple string class. - */ -#include "ace/SOCK_Connector.h" -#include "ace/SString.h" - -/* - In this tutorial, we extend SOCK_Stream by adding a few wrappers - around the send_n() method. - */ -class Client : public ACE_SOCK_Stream -{ - -public: - // Basic constructor - Client(void); - - /* - Construct and open() in one call. This isn't generally a good - idea because you don't have a clean way to inform the caller - when open() fails. (Unless you use C++ exceptions.) - */ - Client( const char * server, u_short port ); - - /* - Open the connection to the server. Notice that this mirrors - the use of ACE_SOCK_Connector. By providing our own open(), - we can hide the connector from our caller & make it's interaction - easier. - */ - int open( const char * server, u_short port ); - - /* - These are necessary if you're going to use the constructor that - invokes open(). - */ - inline int initialized(void) { return initialized_; } - inline int error(void) { return error_; } - - /* - This is where the coolness lies. Most C++ folks are familiar - with "cout << some-data". It's a very handy and easy way to - toss data around. By adding these method calls, we're able - to do the same thing with a socket connection. - */ - Client & operator<<( ACE_SString & str ); - Client & operator<<( char * str ); - Client & operator<<( int n ); - -protected: - unsigned char initialized_; - unsigned char error_; - -}; - -/* - The basic constructor just sets our flags to reasonable values. - */ -Client::Client(void) -{ - initialized_ = 0; - error_ = 0; -} - -/* - This constructor also sets the flags but then calls open(). If the - open() fails, the flags will be set appropriately. Use the two inline - method calls initialized() and error() to check the object state after - using this constructor. - */ -Client::Client( const char * server, u_short port ) -{ - initialized_ = 0; - error_ = 0; - (void)open(server,port); -} - -/* - Open a connection to the server. This hides the use of ACE_SOCK_Connector - from our caller. Since our caller probably doesn't care *how* we connect, - this is a good thing. - */ -int Client::open( const char * server, u_short port ) -{ - /* - This is right out of Tutorial 3. The only thing we've added is to set - the initialized_ member variable on success. - */ - - ACE_SOCK_Connector connector; - ACE_INET_Addr addr (port, server); - - if (connector.connect (*this, addr) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - initialized_ = 1; - - return(0); -} - -/* - The first of our put operators sends a simple string object to the peer. -*/ -Client & Client::operator<<( ACE_SString & str ) -{ - /* - We have to be able to allow: - server << foo << bar << stuff; - - To accomplish that, every << operator must check that the object is - in a valid state before doing work. - */ - - if( initialized() && ! error() ) - { - /* - Get the actual data held in the string object - */ - const char * cp = str.rep(); - - /* - Send that data to the peer using send_n() as before. If we have - a problem, we'll set error_ so that subsequent << operations won't - try to use a broken stream. - */ - if( this->send_n(cp,strlen(cp)) == -1 ) - { - error_ = 1; - } - } - else - { - /* - Be sure that error_ is set if somebody tries to use us when - we're not initialized. - */ - error_ = 1; - } - - /* - We have to return a reference to ourselves to allow chaining of - put operations (eg -- "server << foo << bar"). Without the reference, - you would have to do each put operation as a statement. That's OK - but doesn't have the same feel as standard C++ iostreams. - */ - return *this ; -} - -/* -How do you put a char*? We'll take an easy way out and construct an ACE_SString -from the char* and then put that. It would have been more efficient to implement -this with the body of the operator<<(ACE_SString&) method and then express that -method in terms of this one. There's always more than one way to do things! - */ -Client & Client::operator<< ( char * str ) -{ - ACE_SString newStr(str); - - *this << newStr; - - return *this ; - - /* - Notice that we could have been really clever and done: - - return *this << ACE_SString(str); - - That kind of thing just makes debugging a pain though! - */ -} - -/* - ACE_SString and char* are both about the same thing. What do you do about - different datatypes though? - - Do the same thing we did with char* and convert it to ACE_SString where we - already have a << operator defined. - */ -Client & Client::operator<< ( int n ) -{ - /* - Create a character buffer large enough for the largest number. That's - a tough call but 1024 should be quite enough. - */ - char buf[1024]; - - /* - Put the number into our buffer... - */ - ACE_OS::sprintf(buf,"(%d)\n",n); - - /* - And create the ACE_SString that we know how to put. - */ - ACE_SString newStr(buf); - - /* - Send it and... - */ - *this << newStr; - - /* - return ourselves as usual. - */ - return *this; -} - - -/* - Now we pull it all together. Like Tutorial 3, we'll allow command line options. - */ -int main (int argc, char *argv[]) -{ - const char *server_host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; - u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; - int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : 4; - - /* - Use the basic constructor since the other isn't really very safe. - */ - Client server; - - /* - Open the server connection. Notice how this is simpler than Tutorial 3 - since we only have to provide a host name and port value. - */ - if( server.open(server_host,server_port) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - for (int i = 0; i < max_iterations; i++) - { - /* - Tell the server which iteration we're on. No more mucking aroudn with - sprintf at this level! It's all hidden from us. - */ - server << "message = " << i+1; - - /* - Everything OK? - */ - if ( server.error() ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); - } - else - { - ACE_OS::sleep (1); - } - } - - if (server.close () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); - } - - return 0; -} diff --git a/docs/tutorials/004/page01.html b/docs/tutorials/004/page01.html deleted file mode 100644 index a6e69c5eb98..00000000000 --- a/docs/tutorials/004/page01.html +++ /dev/null @@ -1,316 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 004</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 004</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>A much more clever Client</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Ok, so the last time around, we learned how to create a simple client -that can send a chunk of data. A cooler thing to do is to overload -the C++ put operator (<<) to put some data for us. That's what -we're going to do this time. (This tutorial is actually where ACE_IOStream -was born.) - -<P> -<HR WIDTH="100%"> -<PRE>/* - We need the connector object & we also bring in a simple string class. - */ -#include "ace/SOCK_Connector.h" -#include "ace/SString.h" - -/* - In this tutorial, we extend SOCK_Stream by adding a few wrappers - around the send_n() method. - */ -class Client : public ACE_SOCK_Stream -{ - -public: - // Basic constructor - Client(void); - - /* - Construct and open() in one call. This isn't generally a good - idea because you don't have a clean way to inform the caller - when open() fails. (Unless you use C++ exceptions.) - */ - Client( const char * server, u_short port ); - - /* - Open the connection to the server. Notice that this mirrors - the use of ACE_SOCK_Connector. By providing our own open(), - we can hide the connector from our caller & make it's interaction - easier. - */ - int open( const char * server, u_short port ); - - /* - These are necessary if you're going to use the constructor that - invokes open(). - */ - inline int initialized(void) { return initialized_; } - inline int error(void) { return error_; } - - /* - This is where the coolness lies. Most C++ folks are familiar - with "cout << some-data". It's a very handy and easy way to - toss data around. By adding these method calls, we're able - to do the same thing with a socket connection. - */ - Client & operator<<( ACE_SString & str ); - Client & operator<<( char * str ); - Client & operator<<( int n ); - -protected: - unsigned char initialized_; - unsigned char error_; - -}; - -/* - The basic constructor just sets our flags to reasonable values. - */ -Client::Client(void) -{ - initialized_ = 0; - error_ = 0; -} - -/* - This constructor also sets the flags but then calls open(). If the - open() fails, the flags will be set appropriately. Use the two inline - method calls initialized() and error() to check the object state after - using this constructor. - */ -Client::Client( const char * server, u_short port ) -{ - initialized_ = 0; - error_ = 0; - (void)open(server,port); -} - -/* - Open a connection to the server. This hides the use of ACE_SOCK_Connector - from our caller. Since our caller probably doesn't care *how* we connect, - this is a good thing. - */ -int Client::open( const char * server, u_short port ) -{ - /* - This is right out of Tutorial 3. The only thing we've added is to set - the initialized_ member variable on success. - */ - - ACE_SOCK_Connector connector; - ACE_INET_Addr addr (port, server); - - if (connector.connect (*this, addr) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - initialized_ = 1; - - return(0); -} - -/* - The first of our put operators sends a simple string object to the peer. -*/ -Client & Client::operator<<( ACE_SString & str ) -{ - /* - We have to be able to allow: - server << foo << bar << stuff; - - To accomplish that, every << operator must check that the object is - in a valid state before doing work. - */ - - if( initialized() && ! error() ) - { - /* - Get the actual data held in the string object - */ - char * cp = str.rep(); - - /* - Send that data to the peer using send_n() as before. If we have - a problem, we'll set error_ so that subsequent << operations won't - try to use a broken stream. - */ - if( this->send_n(cp,strlen(cp)) == -1 ) - { - error_ = 1; - } - } - else - { - /* - Be sure that error_ is set if somebody tries to use us when - we're not initialized. - */ - error_ = 1; - } - - /* - We have to return a reference to ourselves to allow chaining of - put operations (eg -- "server << foo << bar"). Without the reference, - you would have to do each put operation as a statement. That's OK - but doesn't have the same feel as standard C++ iostreams. - */ - return *this ; -} - -/* -How do you put a char*? We'll take an easy way out and construct an ACE_SString -from the char* and then put that. It would have been more efficient to implement -this with the body of the operator<<(ACE_SString&) method and then express that -method in terms of this one. There's always more than one way to do things! - */ -Client & Client::operator<< ( char * str ) -{ - ACE_SString newStr(str); - - *this << newStr; - - return *this ; - - /* - Notice that we could have been really clever and done: - - return *this << ACE_SString(str); - - That kind of thing just makes debugging a pain though! - */ -} - -/* - ACE_SString and char* are both about the same thing. What do you do about - different datatypes though? - - Do the same thing we did with char* and convert it to ACE_SString where we - already have a << operator defined. - */ -Client & Client::operator<< ( int n ) -{ - /* - Create a character buffer large enough for the largest number. That's - a tough call but 1024 should be quite enough. - */ - char buf[1024]; - - /* - Put the number into our buffer... - */ - ACE_OS::sprintf(buf,"(%d)\n",n); - - /* - And create the ACE_SString that we know how to put. - */ - ACE_SString newStr(buf); - - /* - Send it and... - */ - *this << newStr; - - /* - return ourselves as usual. - */ - return *this; -} - - -/* - Now we pull it all together. Like Tutorial 3, we'll allow command line options. - */ -int main (int argc, char *argv[]) -{ - const char *server_host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; - u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; - int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : 4; - - /* - Use the basic constructor since the other isn't really very safe. - */ - Client server; - - /* - Open the server connection. Notice how this is simpler than Tutorial 3 - since we only have to provide a host name and port value. - */ - if( server.open(server_host,server_port) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - for (int i = 0; i < max_iterations; i++) - { - /* - Tell the server which iteration we're on. No more mucking aroudn with - sprintf at this level! It's all hidden from us. - */ - server << "message = " << i+1; - - /* - Everything OK? - */ - if ( server.error() ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); - } - else - { - ACE_OS::sleep (1); - } - } - - if (server.close () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); - } - - return 0; -}</PRE> - -<HR WIDTH="100%"> - -<P>Ok, now we're done with that. As you can see, it really isn't -so hard to create an object that makes sending data much more "natural" -than the typical send() or send_n() invocation. You can even build -up arbitrary objects & do some neat tricks with C++ templates to stream -their data out as well. (We may go into that a little later.) -Of course, writting the full implementation such that these streams are -interchangable with the standard C++ ostreams is quite a bit more difficult. -In addition, there are a lot of optimizations that this client would benefit -from! - -<P>As an exercise to the reader (don't you hate those!) I challenge you -to write the server side of this. You can take a look at IOStream_Test -in the ACE distribution if you get stuck... - -<P>If you want to compile it yourself, here's the <A HREF="client.cpp">source</A>, -the <A HREF="Makefile">Makefile</A>, -and <A HREF="00SetEnv">Environment -settings</A>. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/005.dsp b/docs/tutorials/005/005.dsp deleted file mode 100644 index 024b1aef6b7..00000000000 --- a/docs/tutorials/005/005.dsp +++ /dev/null @@ -1,112 +0,0 @@ -# Microsoft Developer Studio Project File - Name="005" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=005 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "005.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "005.mak" CFG="005 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "005 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "005 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "005 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "005 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "005 - Win32 Release"
-# Name "005 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\client_handler.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\client_acceptor.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\client_handler.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/005/00SetEnv b/docs/tutorials/005/00SetEnv deleted file mode 100644 index eca78e10c85..00000000000 --- a/docs/tutorials/005/00SetEnv +++ /dev/null @@ -1,2 +0,0 @@ -export ACE_ROOT=/local/src/ACE/ACE_wrappers -export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH diff --git a/docs/tutorials/005/Makefile b/docs/tutorials/005/Makefile deleted file mode 100644 index 6c4b01dbf9c..00000000000 --- a/docs/tutorials/005/Makefile +++ /dev/null @@ -1,99 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -# You can generally find a Makefile in the ACE examples, tests or the library -# itself that will satisfy our application needs. This one was taken from -# one of the examples. - - # Define the name of the binary we want to create. There has to be - # a CPP file $(BIN).cpp but it doesn't necessarily have to have your - # main() in it. Most of the time, though, it will. -BIN = server - - # Few applications will have a single source file. We use the FILES - # macro to build up a list of additional files to compile. Notice - # that we leave off the extension just as with BIN -FILES = -FILES += client_handler - - # The BUILD macro is used by the ACE makefiles. Basically, it tells - # the system what to build. I don't really know what VBIN is other - # than it is constructed from the value of BIN. Just go with it... -BUILD = $(VBIN) - - # Here we use some GNU make extensions to build the SRC macro. Basically, - # we're just adding .cpp to the value of BIN and for each entry of the - # FILES macro. -SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix .cpp,$(FILES)) - - # This is used by my Indent target below. It's not a part of standard - # ACE and you don't need it yourself. -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - - # This is where the real power lies! These included makefile components - # are similar to the C++ templates in ACE. That is, they do a tremendous - # amount of work for you and all you have to do is include them. - # As a matter of fact, in our project, I created a single file named - # "app.mk" that includes all of these. Our project makefiles then just - # need to include app.mk to get everything they need. - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - - # Sometimes I like to reformat my code to make it more readable. This is - # more useful for the comments than anything else. Unfortunately, the - # "indent" program doesn't quite grok C++ so I have to post-process it's - # output just a bit. -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - - # One of the targets in the ACE makefiles is "depend". It will invoke - # your compiler in a way that will generate a list of dependencies for - # you. This is a great thing! Unfortunately, it puts all of that mess - # directly into the Makefile. I prefer my Makefile to stay clean and - # uncluttered. The perl script referenced here pulls the dependency - # stuff back out of the Makefile and into a file ".depend" which we then - # include just like the makefile components above. -Depend : depend - perl fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! - - # This is inserted by the fix.Makefile script -include .depend diff --git a/docs/tutorials/005/acceptor b/docs/tutorials/005/acceptor deleted file mode 100644 index 45409e4ec3e..00000000000 --- a/docs/tutorials/005/acceptor +++ /dev/null @@ -1,6 +0,0 @@ - -1. #include "ace/Acceptor.h" -2. #include "ace/SOCK_Acceptor.h" - -3. typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Logging_Acceptor; - diff --git a/docs/tutorials/005/client_acceptor.h b/docs/tutorials/005/client_acceptor.h deleted file mode 100644 index fa3d3b41be8..00000000000 --- a/docs/tutorials/005/client_acceptor.h +++ /dev/null @@ -1,45 +0,0 @@ - -// $Id$ - -#ifndef CLIENT_ACCEPTOR_H -#define CLIENT_ACCEPTOR_H - -/* - The ACE_Acceptor<> template lives in the ace/Acceptor.h header file. You'll - find a very consitent naming convention between the ACE objects and the - headers where they can be found. In general, the ACE object ACE_Foobar will - - - be found in ace/Foobar.h. - */ - -#include "ace/Acceptor.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - Since we want to work with sockets, we'll need a SOCK_Acceptor to allow the - clients to connect to us. - */ -#include "ace/SOCK_Acceptor.h" - -/* - The Client_Handler object we develop will be used to handle clients once - they're connected. The ACE_Acceptor<> template's first parameter requires - such an object. In some cases, you can get by with just a forward - declaration on the class, in others you have to have the whole thing. - */ -#include "client_handler.h" - -/* - Parameterize the ACE_Acceptor<> such that it will listen for socket - connection attempts and create Client_Handler objects when they happen. In - Tutorial 001, we wrote the basic acceptor logic on our own before we - realized that ACE_Acceptor<> was available. You'll get spoiled using the - ACE templates because they take away a lot of the tedious details! - */ -typedef ACE_Acceptor < Client_Handler, ACE_SOCK_ACCEPTOR > Client_Acceptor; - -#endif // CLIENT_ACCEPTOR_H diff --git a/docs/tutorials/005/client_handler.cpp b/docs/tutorials/005/client_handler.cpp deleted file mode 100644 index 84f2d98d6bb..00000000000 --- a/docs/tutorials/005/client_handler.cpp +++ /dev/null @@ -1,231 +0,0 @@ - -// $Id$ - -/* - In client_handler.h I alluded to the fact that we'll mess around with a - Client_Acceptor pointer. To do so, we need the Client_Acceptor object - declaration. - - We know that including client_handler.h is redundant because - client_acceptor.h includes it. Still, the sentry prevents double-inclusion - from causing problems and it's sometimes good to be explicit about what - we're using. - - On the other hand, we don't directly include any ACE header files here. - */ -#include "client_acceptor.h" -#include "client_handler.h" - -/* - Our constructor doesn't do anything. That's generally a good idea. Unless - you want to start throwing exceptions, there isn't a really good way to - indicate that a constructor has failed. If I had my way, I'd have a boolean - return code from it that would cause new to return 0 if I failed. Oh - well... - */ -Client_Handler::Client_Handler (void) -{ -} - -/* - Our destructor doesn't do anything either. That is also by design. - Remember, we really want folks to use destroy() to get rid of us. If that's - so, then there's nothing left to do when the destructor gets invoked. - */ -Client_Handler::~Client_Handler (void) -{ - // Make sure that our peer closes when we're deleted. This - // will probably happend when the peer is deleted but it - // doesn't hurt to be explicit. - this->peer ().close (); -} - -/* - The much talked about destroy() method! The reason I keep going on about - this is because it's just a Bad Idea (TM) to do real work inside of a - destructor. Although this method is void, it really should return - int so that it can tell the caller there was a problem. Even as - void you could at least throw an exception which you would never want - to do in a destructor. - */ -void Client_Handler::destroy (void) -{ - /* - Tell the reactor to forget all about us. Notice that we use the same args - here that we use in the open() method to register ourselves. In addition, - we use the DONT_CALL flag to prevent handle_close() being called. Since we - likely got here due to handle_close(), that could cause a bit of nasty - recursion! - */ - this->reactor ()->remove_handler (this, - ACE_Event_Handler:: READ_MASK | ACE_Event_Handler::DONT_CALL); - - /* - This is how we're able to tell folks not to use delete. By - deleting our own instance, we take care of memory leaks after ensuring - that the object is shut down correctly. - */ - delete this; -} - -/* - As mentioned before, the open() method is called by the Client_Acceptor when - a new client connection has been accepted. The Client_Acceptor instance - pointer is cast to a void* and given to us here. We'll use that to avoid - some global data... - */ -int Client_Handler::open (void *_acceptor) -{ - /* - Convert the void* to a Client_Acceptor*. You should probably use those - fancy new C++ cast operators but I can never remember how/when to do so. - Since you can cast just about anything around a void* without compiler - warnings be very sure of what you're doing when you do this kind of thing. - That's where the new-style cast operators can save you. - */ - Client_Acceptor *acceptor = (Client_Acceptor *) _acceptor; - - /* - Our reactor reference will be set when we register ourselves but I decided - to go ahead and set it here. No good reason really... - */ - this->reactor (acceptor->reactor ()); - - /* - We need this to store the address of the client that we are now connected - to. We'll use it later to display a debug message. - */ - ACE_INET_Addr addr; - - /* - Our ACE_Svc_Handler baseclass gives us the peer() method as a way to - access our underlying ACE_SOCK_Stream. On that object, we can invoke the - get_remote_addr() method to get get an ACE_INET_Addr having our client's - address information. As with most ACE methods, we'll get back (and return) - a -1 if there was any kind of error. Once we have the ACE_INET_Addr, we - can query it to find out the clien's host name, TCP/IP address, TCP/IP - port value and so forth. One word of warning: the get_host_name() - method of ACE_INET_Addr may return you an empty string if your name server - can't resolve it. On the other hand, get_host_addr() will always give you - the dotted-decimal string representing the TCP/IP address. - */ - if (this->peer ().get_remote_addr (addr) == -1) - { - return -1; - } - - /* - If we managed to get the client's address then we're connected to a real - and valid client. I suppose that in some cases, the client may connect - and disconnect so quickly that it is invalid by the time we get here. In - any case, the test above should always be done to ensure that the - connection is worth keeping. - - Now, regiser ourselves with a reactor and tell that reactor that we want - to be notified when there is something to read. Remember, we took our - reactor value from the acceptor which created us in the first place. - Since we're exploring a single-threaded implementation, this is the - correct thing to do. - */ - if (this->reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - } - - /* - Here, we use the ACE_INET_Addr object to print a message with the name of - the client we're connected to. Again, it is possible that you'll get an - empty string for the host name if your DNS isn't configured correctly or - if there is some other reason that a TCP/IP addreess cannot be converted - into a host name. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ())); - - /* - Always return zero on success. - */ - return 0; -} - -/* - In the open() method, we registered with the reactor and requested to be - notified when there is data to be read. When the reactor sees that activity - it will invoke this handle_input() method on us. As I mentioned, the _handle - parameter isn't useful to us but it narrows the list of methods the reactor - has to worry about and the list of possible virtual functions we would have - to override. - */ -int Client_Handler::handle_input (ACE_HANDLE _handle) -{ - /* - Some compilers don't like it when you fail to use a parameter. This macro - will keep 'em quiet for you. - */ - ACE_UNUSED_ARG (_handle); - - /* - Now, we create and initialize a buffer for receiving the data. Since this - is just a simple test app, we'll use a small buffer size. - */ - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the process() method with a pointer to our data area. We'll let - that method worry about interfacing with the data. You might choose to go - ahead and read the data and then pass the result to process(). However, - application logic may require that you read a few bytes to determine what - else to read... It's best if we push that all into the application-logic - level. - */ - return this->process (buf, sizeof (buf)); -} - -/* - If we return -1 out of handle_input() or if the reactor sees other problems - with us then handle_close() will be called. The reactor framework - will take care of removing us (due to the -1), so we don't need to - use the destroy() method. Instead, we just delete ourselves directly. - */ -int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask) -{ - ACE_UNUSED_ARG (_handle); - ACE_UNUSED_ARG (_mask); - - delete this; - return 0; -} - -/* - And, at last, we get to the application-logic level. Out of everything - we've done so far, this is the only thing that really has anything to do - with what your application will do. In this method we will read and process - the client's data. In a real appliation, you will probably have a bit more - in main() to deal with command line options but after that point, all of the - action takes place here. - */ -int Client_Handler::process (char *_rdbuf, int _rdbuf_len) -{ - /* - Using the buffer provided for us, we read the data from the client. If - there is a read error (eg -- recv() returns -1) then it's a pretty good - bet that the connection is gone. Likewise, if we read zero bytes then - something wrong has happened. The reactor wouldn't have called us if - there wasn't some kind of read activity but there wouldn't be activity if - there were no bytes to read... - - On the other hand, if we got some data then we can display it in a debug - message for everyone to see. - */ - switch (this->peer ().recv (_rdbuf, _rdbuf_len)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf)); - } - - return 0; -} diff --git a/docs/tutorials/005/client_handler.h b/docs/tutorials/005/client_handler.h deleted file mode 100644 index f9d6a44454f..00000000000 --- a/docs/tutorials/005/client_handler.h +++ /dev/null @@ -1,111 +0,0 @@ - -// $Id$ - -#ifndef CLIENT_HANDLER_H -#define CLIENT_HANDLER_H - -/* - Our client handler must exist somewhere in the ACE_Event_Handler object - hierarchy. This is a requirement of the ACE_Reactor because it maintains - ACE_Event_Handler pointers for each registered event handler. You could - derive our Client_Handler directly from ACE_Event_Handler but you still have - to have an ACE_SOCK_Stream for the actually connection. With a direct - derivative of ACE_Event_Handler, you'll have to contain and maintain an - ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a - derivative of ACE_Event_Handler) some of those details are handled for you. - - */ - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" - -/* - Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<> - interface as well. That's what the ACE_NULL_SYNCH parameter below is all - about. That's beyond our scope here but we'll come back to it in the next - tutorial when we start looking at concurrency options. - */ -class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - - // Constructor... - Client_Handler (void); - - /* - The destroy() method is our preferred method of destruction. We could - have overloaded the delete operator but that is neither easy nor - intuitive (at least to me). Instead, we provide a new method of - destruction and we make our destructor protected so that only ourselves, - our derivatives and our friends can delete us. It's a nice - compromise. - */ - void destroy (void); - - /* - Most ACE objects have an open() method. That's how you make them ready - to do work. ACE_Event_Handler has a virtual open() method which allows us - to create this overrride. ACE_Acceptor<> will invoke this method after - creating a new Client_Handler when a client connects. Notice that the - parameter to open() is a void*. It just so happens that the pointer - points to the acceptor which created us. You would like for the parameter - to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that - would tie it too closely to the ACE_Acceptor<> set of objects. In our - definition of open() you'll see how we get around that. - */ - int open (void *_acceptor); - - /* - When there is activity on a registered handler, the handle_input() method - of the handler will be invoked. If that method returns an error code (eg - -- -1) then the reactor will invoke handle_close() to allow the object to - clean itself up. Since an event handler can be registered for more than - one type of callback, the callback mask is provided to inform - handle_close() exactly which method failed. That way, you don't have to - maintain state information between your handle_* method calls. The _handle - parameter is explained below... - As a side-effect, the reactor will also invoke remove_handler() - for the object on the mask that caused the -1 return. This means - that we don't have to do that ourselves! - */ - int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask); - -protected: - - /* - When we register with the reactor, we're going to tell it that we want to - be notified of READ events. When the reactor sees that there is read - activity for us, our handle_input() will be invoked. The _handleg - provided is the handle (file descriptor in Unix) of the actual connection - causing the activity. Since we're derived from ACE_Svc_Handler<> and it - maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for - us. However, if we had been derived directly from ACE_Event_Handler, we - may have chosen not to contain the peer. In that case, the _handleg - would be important to us for reading the client's data. - */ - int handle_input (ACE_HANDLE _handle); - - /* - This has nothing at all to do with ACE. I've added this here as a worker - function which I will call from handle_input(). That allows me to - introduce concurrencly in later tutorials with a no changes to the worker - function. You can think of process() as application-level code and - everything elase as application-framework code. - */ - int process (char *_rdbuf, int _rdbuf_len); - - /* - We don't really do anything in our destructor but we've declared it to be - protected to prevent casual deletion of this object. As I said above, I - really would prefer that everyone goes through the destroy() method to get - rid of us. - */ - ~Client_Handler (void); -}; - -#endif // CLIENT_HANDLER_H diff --git a/docs/tutorials/005/fix.Makefile b/docs/tutorials/005/fix.Makefile deleted file mode 100644 index e99c194114a..00000000000 --- a/docs/tutorials/005/fix.Makefile +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/perl - - # Open the Makefile that has been mangled by 'make depend' - # and suck it into a perl array. -open(IF,"<Makefile") || die; -@makefile = <IF>; -close(IF); - - # Now open our .depend file and a temporary Makefile. - # We'll split the original Makefile between these two. -open(DF,">.depend") || die; -open(MF,">Makefile.tmp") || die; - - # For each line we read out of the original file... -foreach (@makefile) { - - # If we're into the dependency section, write the line - # into the .depend file. - # - if( $depend ) { - print DF $_; - } - else { - # If we haven't gotten to the dependency section yet - # then see if the current line is the separator that - # "make depend" causes to be inserted. - # - if( m/^\Q# DO NOT DELETE THIS LINE -- g++dep uses it.\E/ ) { - - # If so, change our "mode" and skip this line. - ++$depend; - next; - } - - # Also skip the "include .depend" that we insert. If we - # don't do this, it is possible to have a bunch of these - # inserted into the output when we read an unmangled Makefile - next if( m/^include .depend/ ); - - # Print the non-dependency info to the temporary Makefile - print MF $_; - } -} - -# Tell our new Makefile to include the dependency file -print MF "include .depend\n"; - -# Close the two output files... -close(DF); -close(MF); - -# Unlink (remove) the original Makefile and rename our -# temporary file. There's obviously room for error checking -# here but we've got the Makefile checked into some revision -# control system anyway. Don't we? - -unlink("Makefile"); -rename("Makefile.tmp","Makefile"); - -exit(0); diff --git a/docs/tutorials/005/handler b/docs/tutorials/005/handler deleted file mode 100644 index d987f4c34ff..00000000000 --- a/docs/tutorials/005/handler +++ /dev/null @@ -1,81 +0,0 @@ - -1. #include "ace/SOCK_Acceptor.h" -2. #include "ace/Reactor.h" - - -3. class Logging_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> - { - - public: - -4. Logging_Handler (void) - { - } - -5. virtual void destroy (void) - { -6. g_reactor->cancel_timer (this); -7. this->peer ().close (); - } - -8. virtual int open (void *) - { -9. ACE_INET_Addr addr; - -10. if (this->peer ().get_remote_addr (addr) == -1) -11. return -1; -12. else - { -13. ACE_OS::strncpy (this->peer_name_, addr.get_host_name (), MAXHOSTNAMELEN + 1); - -14. if (g_reactor->register_handler(this, ACE_Event_Handler::READ_MASK) == -1) -15. ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - -16. else if (g_reactor->schedule_timer (this, (const void *) this, ACE_Time_Value (2), ACE_Time_Value (2)) == -1) -17. ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t register with reactor\n"), -1); - -18. else -19. ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", this->peer_name_)); - -20. return 0; - } - } - -21. virtual int close (u_long) - { -22. this->destroy (); -23. return 0; - } - - protected: - -24. virtual int handle_input (ACE_HANDLE) - { -25. char buf[128]; -26. memset(buf,0,sizeof(buf)); - -27. switch( this->peer().recv(buf,sizeof buf) ) - { -28. case -1: -29. ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1); -30. case 0: -31. ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", this->get_handle ()), -1); -32. default: -33. ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s",buf)); - } - -34. return 0; - } - -35. virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg) - { -36. ACE_ASSERT (arg == this); -37. ACE_DEBUG ((LM_DEBUG, "(%P|%t) handling timeout from this = %u\n", this)); -38. return 0; - } - - private: - -39. char peer_name_[MAXHOSTNAMELEN + 1]; - - }; diff --git a/docs/tutorials/005/main b/docs/tutorials/005/main deleted file mode 100644 index 36c67561463..00000000000 --- a/docs/tutorials/005/main +++ /dev/null @@ -1,36 +0,0 @@ -1. #include "ace/Reactor.h" - -2. ACE_Reactor * g_reactor; - -3. static sig_atomic_t finished = 0; -4. extern "C" void handler (int) { finished = 1; } - -5. static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -6. int main (int argc, char *argv[]) - { -7. g_reactor = new ACE_Reactor; - - // Acceptor factory. -8. Logging_Acceptor peer_acceptor; - -9. if (peer_acceptor.open (ACE_INET_Addr (PORT)) == -1) -10. ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - -11. else if (g_reactor->register_handler (&peer_acceptor, ACE_Event_Handler::READ_MASK) == -1) -12. ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); - -13. ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - // Run forever, performing logging service. - -14. ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); - - // Perform logging service until QUIT_HANDLER receives SIGINT. -15. while ( !finished ) -16. g_reactor->handle_events (); - -17. ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); - -18. return 0; - } diff --git a/docs/tutorials/005/page01.html b/docs/tutorials/005/page01.html deleted file mode 100644 index 60ae178abf3..00000000000 --- a/docs/tutorials/005/page01.html +++ /dev/null @@ -1,38 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="Billy Quinn"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In this tutorial, we're going to flash-back to the simple server we -created a while back. We'll create a very simple server where everything -takes place in one thread. Once we have a solid understanding there, -we'll move on to the next tutorial where we begin to introduce concurrency -concepts. - -<P>There are four C++ source files in this tutorial: server.cpp, -client_acceptor.h, client_handler.h and client_handler.cpp. I'll -talk about each of these in turn with the usual color commentary as we -go. In addition, I'll briefly discuss the Makefile and a short perl -script I've added. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/page02.html b/docs/tutorials/005/page02.html deleted file mode 100644 index 7d268e8bd00..00000000000 --- a/docs/tutorials/005/page02.html +++ /dev/null @@ -1,201 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="Billy Quinn"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>We begin with <I><A HREF="server.cpp">server.cpp</A></I>. - -<P> -<HR WIDTH="100%"> - -<P><FONT FACE="Arial,Helvetica">// $Id: server.cpp,v 1.5 1998/08/29 21:57:32 -jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> We try to keep main() very -simple. One of the ways we do that is to push</FONT> -<BR><FONT FACE="Arial,Helvetica"> much of the complicated stuff -into worker objects. In this case, we only</FONT> -<BR><FONT FACE="Arial,Helvetica"> need to include the acceptor -header in our main source file. We let it</FONT> -<BR><FONT FACE="Arial,Helvetica"> worry about the "real work".</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "client_acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> As before, we create a simple -signal handler that will set our finished</FONT> -<BR><FONT FACE="Arial,Helvetica"> flag. There are, of -course, more elegant ways to handle program shutdown</FONT> -<BR><FONT FACE="Arial,Helvetica"> requests but that isn't really -our focus right now, so we'll just do the</FONT> -<BR><FONT FACE="Arial,Helvetica"> easiest thing.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">static sig_atomic_t finished = 0;</FONT> -<BR><FONT FACE="Arial,Helvetica">extern "C" void handler (int)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> finished = 1;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> A server has to listen for -clients at a known TCP/IP port. The default ACE</FONT> -<BR><FONT FACE="Arial,Helvetica"> port is 10002 (at least on -my system) and that's good enough for what we</FONT> -<BR><FONT FACE="Arial,Helvetica"> want to do here. Obviously, -a more robust application would take a command</FONT> -<BR><FONT FACE="Arial,Helvetica"> line parameter or read from -a configuration file or do some other clever</FONT> -<BR><FONT FACE="Arial,Helvetica"> thing. Just like the -signal handler above, though, that's what we want to</FONT> -<BR><FONT FACE="Arial,Helvetica"> focus on, so we're taking -the easy way out.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Finally, we get to main. -Some C++ compilers will complain loudly if your</FONT> -<BR><FONT FACE="Arial,Helvetica"> function signature doesn't -match the prototype. Even though we're not</FONT> -<BR><FONT FACE="Arial,Helvetica"> going to use the parameters, -we still have to specify them.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">int main (int argc, char *argv[])</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> In our earlier servers, we -used a global pointer to get to the reactor. I've</FONT> -<BR><FONT FACE="Arial,Helvetica"> never really liked that idea, -so I've moved it into main() this time. When</FONT> -<BR><FONT FACE="Arial,Helvetica"> we get to the Client_Handler -object you'll see how we manage to get a</FONT> -<BR><FONT FACE="Arial,Helvetica"> pointer back to this reactor.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_Reactor reactor;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The acceptor -will take care of letting clients connect to us. It will</FONT> -<BR><FONT FACE="Arial,Helvetica"> also arrange -for a Client_Handler to be created for each new client.</FONT> -<BR><FONT FACE="Arial,Helvetica"> Since we're only -going to listen at one TCP/IP port, we only need one</FONT> -<BR><FONT FACE="Arial,Helvetica"> acceptor. -If we wanted, though, we could create several of these and</FONT> -<BR><FONT FACE="Arial,Helvetica"> listen at several -ports. (That's what we would do if we wanted to rewrite</FONT> -<BR><FONT FACE="Arial,Helvetica"> inetd for -instance.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> Client_Acceptor peer_acceptor;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Create an ACE_INET_Addr -that represents our endpoint of a connection. We</FONT> -<BR><FONT FACE="Arial,Helvetica"> then open our -acceptor object with that Addr. Doing so tells the acceptor</FONT> -<BR><FONT FACE="Arial,Helvetica"> where to listen -for connections. Servers generally listen at "well known"</FONT> -<BR><FONT FACE="Arial,Helvetica"> addresses. -If not, there must be some mechanism by which the client is</FONT> -<BR><FONT FACE="Arial,Helvetica"> informed of the -server's address.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> Note how ACE_ERROR_RETURN -is used if we fail to open the acceptor. This</FONT> -<BR><FONT FACE="Arial,Helvetica"> technique is -used over and over again in our tutorials.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> if (peer_acceptor.open (ACE_INET_Addr -(PORT), &reactor) == -1)</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_ERROR_RETURN ((LM_ERROR, -"%p\n", "open"), -1);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Here, we know -that the open was successful. If it had failed, we would</FONT> -<BR><FONT FACE="Arial,Helvetica"> have exited above. -A nice side-effect of the open() is that we're already</FONT> -<BR><FONT FACE="Arial,Helvetica"> registered with -the reactor we provided it.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Install our signal -handler. You can actually register signal handlers</FONT> -<BR><FONT FACE="Arial,Helvetica"> with the reactor. -You might do that when the signal handler is</FONT> -<BR><FONT FACE="Arial,Helvetica"> responsible for -performing "real" work. Our simple flag-setter doesn't</FONT> -<BR><FONT FACE="Arial,Helvetica"> justify deriving -from ACE_Event_Handler and providing a callback function</FONT> -<BR><FONT FACE="Arial,Helvetica"> though.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_Sig_Action sa ((ACE_SignalHandler) -handler, SIGINT);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Like ACE_ERROR_RETURN, -the ACE_DEBUG macro gets used quite a bit. It's a</FONT> -<BR><FONT FACE="Arial,Helvetica"> handy way to -generate uniform debug output from your program.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_DEBUG ((LM_DEBUG, "(%P|%t) -starting up server daemon\n"));</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> This will loop -"forever" invoking the handle_events() method of our</FONT> -<BR><FONT FACE="Arial,Helvetica"> reactor. handle_events() -watches for activity on any registered handlers</FONT> -<BR><FONT FACE="Arial,Helvetica"> and invokes their -appropriate callbacks when necessary. Callback-driven</FONT> -<BR><FONT FACE="Arial,Helvetica"> programming is -a big thing in ACE, you should get used to it. If the</FONT> -<BR><FONT FACE="Arial,Helvetica"> signal handler -catches something, the finished flag will be set and we'll</FONT> -<BR><FONT FACE="Arial,Helvetica"> exit. Conveniently -enough, handle_events() is also interrupted by signals</FONT> -<BR><FONT FACE="Arial,Helvetica"> and will exit -back to the while() loop. (If you want your event loop to</FONT> -<BR><FONT FACE="Arial,Helvetica"> not be interrupted -by signals, checkout the <i>restart</i> flag on the</FONT> -<BR><FONT FACE="Arial,Helvetica"> open() method -of ACE_Reactor if you're interested.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> while (!finished)</FONT> -<BR><FONT FACE="Arial,Helvetica"> reactor.handle_events -();</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting -down server daemon\n"));</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> return 0;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/page03.html b/docs/tutorials/005/page03.html deleted file mode 100644 index fb8acc3e913..00000000000 --- a/docs/tutorials/005/page03.html +++ /dev/null @@ -1,94 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="Billy Quinn"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Now, let's take a look at <I><A HREF="client_acceptor.h">client_acceptor.h</A></I>. -Since I went on about how it does all the work of letting clients connect -to us, it must be rather complext. Right? Wrong. - -<P>The more you use ACE, the more you'll find that they've already taken -care of most details for you. With respect to the acceptance of client -connections: there just aren't that many ways to do it! The -ACE team has chosen an approach and created a C++ template that does -all of the work for you. All you're required to do is provide it -with an object type to instantiate when a new connection arrives. - -<P> -<HR WIDTH="100%"> - -<P><FONT FACE="Arial,Helvetica">// $Id$</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#ifndef CLIENT_ACCEPTOR_H</FONT> -<BR><FONT FACE="Arial,Helvetica">#define CLIENT_ACCEPTOR_H</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The ACE_Acceptor<> template lives -in the ace/Acceptor.h header file.</FONT> -<BR><FONT FACE="Arial,Helvetica"> You'll find a very consitent naming -convention between the ACE objects</FONT> -<BR><FONT FACE="Arial,Helvetica"> and the headers where they can be -found. In general, the ACE object</FONT> -<BR><FONT FACE="Arial,Helvetica"> <I>ACE_Foobar</I> will be found -in <I>ace/Foobar.h</I>.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "ace/Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Since we want to work with sockets, -we'll need a SOCK_Acceptor to allow</FONT> -<BR><FONT FACE="Arial,Helvetica"> the clients to connect to us.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "ace/SOCK_Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The Client_Handler object we develop -will be used to handle clients</FONT> -<BR><FONT FACE="Arial,Helvetica"> once they're connected. The -ACE_Acceptor<> template's first parameter</FONT> -<BR><FONT FACE="Arial,Helvetica"> requires such an object. In -some cases, you can get by with just a</FONT> -<BR><FONT FACE="Arial,Helvetica"> forward declaration on the class, -in others you have to have the whole</FONT> -<BR><FONT FACE="Arial,Helvetica"> thing.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "client_handler.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Parameterize the ACE_Acceptor<> -such that it will listen for socket</FONT> -<BR><FONT FACE="Arial,Helvetica"> connection attempts and create Client_Handler -objects when they happen.</FONT> -<BR><FONT FACE="Arial,Helvetica"> In Tutorial 001, we wrote the basic -acceptor logic on our own before</FONT> -<BR><FONT FACE="Arial,Helvetica"> we realized that ACE_Acceptor<> -was available. You'll get spoiled using</FONT> -<BR><FONT FACE="Arial,Helvetica"> the ACE templates because they take -away a lot of the tedious details!</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">typedef ACE_Acceptor < Client_Handler, -ACE_SOCK_ACCEPTOR > Client_Acceptor;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#endif // CLIENT_ACCEPTOR_H</FONT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/page04.html b/docs/tutorials/005/page04.html deleted file mode 100644 index 2b117894588..00000000000 --- a/docs/tutorials/005/page04.html +++ /dev/null @@ -1,145 +0,0 @@ -<HTML> -<HEAD> -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -<META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> -<META NAME="Author" CONTENT="Billy Quinn"> -<META NAME="Description" CONTENT="A first step towards using ACE productively"> -<TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Ok, so we've got a main() loop that sets up the acceptor and we've seen -how easy it is to create the acceptor object. So far, we've hardly -written any code at all. Well, that's just about to change... - -<P>First, we look at <I><A HREF="client_handler.h">client_handler.h</A></I> -for the declaration of the Client_Handler object. Then we look at -the definition where all of the real work of the application takes place. - -<P> -<HR WIDTH="100%"> - -<pre><FONT FACE="Arial,Helvetica"> -#ifndef CLIENT_HANDLER_H -#define CLIENT_HANDLER_H - -/* - Our client handler must exist somewhere in the ACE_Event_Handler object - hierarchy. This is a requirement of the ACE_Reactor because it maintains - ACE_Event_Handler pointers for each registered event handler. You could - derive our Client_Handler directly from ACE_Event_Handler but you still have - to have an ACE_SOCK_Stream for the actually connection. With a direct - derivative of ACE_Event_Handler, you'll have to contain and maintain an - ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a - derivative of ACE_Event_Handler) some of those details are handled for you. - - */ - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" - -/* - Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<> - interface as well. That's what the ACE_NULL_SYNCH parameter below is all - about. That's beyond our scope here but we'll come back to it in the next - tutorial when we start looking at concurrency options. - */ -class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - - // Constructor... - Client_Handler (void); - - /* - The destroy() method is our preferred method of destruction. We could - have overloaded the delete operator but that is neither easy nor - intuitive (at least to me). Instead, we provide a new method of - destruction and we make our destructor protected so that only ourselves, - our derivatives and our friends can delete us. It's a nice - compromise. - */ - void destroy (void); - - /* - Most ACE objects have an open() method. That's how you make them ready - to do work. ACE_Event_Handler has a virtual open() method which allows us - to create this overrride. ACE_Acceptor<> will invoke this method after - creating a new Client_Handler when a client connects. Notice that the - parameter to open() is a void*. It just so happens that the pointer - points to the acceptor which created us. You would like for the parameter - to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that - would tie it too closely to the ACE_Acceptor<> set of objects. In our - definition of open() you'll see how we get around that. - */ - int open (void *_acceptor); - - /* - When there is activity on a registered handler, the handle_input() method - of the handler will be invoked. If that method returns an error code (eg - -- -1) then the reactor will invoke handle_close() to allow the object to - clean itself up. Since an event handler can be registered for more than - one type of callback, the callback mask is provided to inform - handle_close() exactly which method failed. That way, you don't have to - maintain state information between your handle_* method calls. The _handle - parameter is explained below... - As a side-effect, the reactor will also invoke remove_handler() - for the object on the mask that caused the -1 return. This means - that we don't have to do that ourselves! - */ - int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask); - -protected: - - /* - When we register with the reactor, we're going to tell it that we want to - be notified of READ events. When the reactor sees that there is read - activity for us, our handle_input() will be invoked. The _handleg - provided is the handle (file descriptor in Unix) of the actual connection - causing the activity. Since we're derived from ACE_Svc_Handler<> and it - maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for - us. However, if we had been derived directly from ACE_Event_Handler, we - may have chosen not to contain the peer. In that case, the _handleg - would be important to us for reading the client's data. - */ - int handle_input (ACE_HANDLE _handle); - - /* - This has nothing at all to do with ACE. I've added this here as a worker - function which I will call from handle_input(). That allows me to - introduce concurrencly in later tutorials with a no changes to the worker - function. You can think of process() as application-level code and - everything elase as application-framework code. - */ - int process (char *_rdbuf, int _rdbuf_len); - - /* - We don't really do anything in our destructor but we've declared it to be - protected to prevent casual deletion of this object. As I said above, I - really would prefer that everyone goes through the destroy() method to get - rid of us. - */ - ~Client_Handler (void); -}; - -#endif // CLIENT_HANDLER_H -</pre> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/page05.html b/docs/tutorials/005/page05.html deleted file mode 100644 index dc96480cc8d..00000000000 --- a/docs/tutorials/005/page05.html +++ /dev/null @@ -1,268 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="Billy Quinn"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Now we're finally at <I><A HREF="client_handler.cpp">client_handler.cpp</A></I> -where we have to write some code. This file has more code than the -rest of the application all together. - -<P> -<HR WIDTH="100%"> -<pre> -<FONT FACE="Arial,Helvetica"> -/* - In client_handler.h I alluded to the fact that we'll mess around with a - Client_Acceptor pointer. To do so, we need the Client_Acceptor object - declaration. - - We know that including client_handler.h is redundant because - client_acceptor.h includes it. Still, the sentry prevents double-inclusion - from causing problems and it's sometimes good to be explicit about what - we're using. - - On the other hand, we don't directly include any ACE header files here. - */ -#include "client_acceptor.h" -#include "client_handler.h" - -/* - Our constructor doesn't do anything. That's generally a good idea. Unless - you want to start throwing exceptions, there isn't a really good way to - indicate that a constructor has failed. If I had my way, I'd have a boolean - return code from it that would cause new to return 0 if I failed. Oh - well... - */ -Client_Handler::Client_Handler (void) -{ -} - -/* - Our destructor doesn't do anything either. That is also by design. - Remember, we really want folks to use destroy() to get rid of us. If that's - so, then there's nothing left to do when the destructor gets invoked. - */ -Client_Handler::~Client_Handler (void) -{ - // Make sure that our peer closes when we're deleted. This - // will probably happend when the peer is deleted but it - // doesn't hurt to be explicit. - this->peer ().close (); -} - -/* - The much talked about destroy() method! The reason I keep going on about - this is because it's just a Bad Idea (TM) to do real work inside of a - destructor. Although this method is void, it really should return - int so that it can tell the caller there was a problem. Even as - void you could at least throw an exception which you would never want - to do in a destructor. - */ -void Client_Handler::destroy (void) -{ - /* - Tell the reactor to forget all about us. Notice that we use the same args - here that we use in the open() method to register ourselves. In addition, - we use the DONT_CALL flag to prevent handle_close() being called. Since we - likely got here due to handle_close(), that could cause a bit of nasty - recursion! - */ - this->reactor ()->remove_handler (this, - ACE_Event_Handler:: READ_MASK | ACE_Event_Handler::DONT_CALL); - - /* - This is how we're able to tell folks not to use delete. By - deleting our own instance, we take care of memory leaks after ensuring - that the object is shut down correctly. - */ - delete this; -} - -/* - As mentioned before, the open() method is called by the Client_Acceptor when - a new client connection has been accepted. The Client_Acceptor instance - pointer is cast to a void* and given to us here. We'll use that to avoid - some global data... - */ -int Client_Handler::open (void *_acceptor) -{ - /* - Convert the void* to a Client_Acceptor*. You should probably use those - fancy new C++ cast operators but I can never remember how/when to do so. - Since you can cast just about anything around a void* without compiler - warnings be very sure of what you're doing when you do this kind of thing. - That's where the new-style cast operators can save you. - */ - Client_Acceptor *acceptor = (Client_Acceptor *) _acceptor; - - /* - Our reactor reference will be set when we register ourselves but I decided - to go ahead and set it here. No good reason really... - */ - this->reactor (acceptor->reactor ()); - - /* - We need this to store the address of the client that we are now connected - to. We'll use it later to display a debug message. - */ - ACE_INET_Addr addr; - - /* - Our ACE_Svc_Handler baseclass gives us the peer() method as a way to - access our underlying ACE_SOCK_Stream. On that object, we can invoke the - get_remote_addr() method to get get an ACE_INET_Addr having our client's - address information. As with most ACE methods, we'll get back (and return) - a -1 if there was any kind of error. Once we have the ACE_INET_Addr, we - can query it to find out the clien's host name, TCP/IP address, TCP/IP - port value and so forth. One word of warning: the get_host_name() - method of ACE_INET_Addr may return you an empty string if your name server - can't resolve it. On the other hand, get_host_addr() will always give you - the dotted-decimal string representing the TCP/IP address. - */ - if (this->peer ().get_remote_addr (addr) == -1) - { - return -1; - } - - /* - If we managed to get the client's address then we're connected to a real - and valid client. I suppose that in some cases, the client may connect - and disconnect so quickly that it is invalid by the time we get here. In - any case, the test above should always be done to ensure that the - connection is worth keeping. - - Now, regiser ourselves with a reactor and tell that reactor that we want - to be notified when there is something to read. Remember, we took our - reactor value from the acceptor which created us in the first place. - Since we're exploring a single-threaded implementation, this is the - correct thing to do. - */ - if (this->reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - } - - /* - Here, we use the ACE_INET_Addr object to print a message with the name of - the client we're connected to. Again, it is possible that you'll get an - empty string for the host name if your DNS isn't configured correctly or - if there is some other reason that a TCP/IP addreess cannot be converted - into a host name. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ())); - - /* - Always return zero on success. - */ - return 0; -} - -/* - In the open() method, we registered with the reactor and requested to be - notified when there is data to be read. When the reactor sees that activity - it will invoke this handle_input() method on us. As I mentioned, the _handle - parameter isn't useful to us but it narrows the list of methods the reactor - has to worry about and the list of possible virtual functions we would have - to override. - */ -int Client_Handler::handle_input (ACE_HANDLE _handle) -{ - /* - Some compilers don't like it when you fail to use a parameter. This macro - will keep 'em quiet for you. - */ - ACE_UNUSED_ARG (_handle); - - /* - Now, we create and initialize a buffer for receiving the data. Since this - is just a simple test app, we'll use a small buffer size. - */ - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the process() method with a pointer to our data area. We'll let - that method worry about interfacing with the data. You might choose to go - ahead and read the data and then pass the result to process(). However, - application logic may require that you read a few bytes to determine what - else to read... It's best if we push that all into the application-logic - level. - */ - return this->process (buf, sizeof (buf)); -} - -/* - If we return -1 out of handle_input() or if the reactor sees other problems - with us then handle_close() will be called. The reactor framework - will take care of removing us (due to the -1), so we don't need to - use the destroy() method. Instead, we just delete ourselves directly. - */ -int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask) -{ - ACE_UNUSED_ARG (_handle); - ACE_UNUSED_ARG (_mask); - - delete this; - return 0; -} - -/* - And, at last, we get to the application-logic level. Out of everything - we've done so far, this is the only thing that really has anything to do - with what your application will do. In this method we will read and process - the client's data. In a real appliation, you will probably have a bit more - in main() to deal with command line options but after that point, all of the - action takes place here. - */ -int Client_Handler::process (char *_rdbuf, int _rdbuf_len) -{ - /* - Using the buffer provided for us, we read the data from the client. If - there is a read error (eg -- recv() returns -1) then it's a pretty good - bet that the connection is gone. Likewise, if we read zero bytes then - something wrong has happened. The reactor wouldn't have called us if - there wasn't some kind of read activity but there wouldn't be activity if - there were no bytes to read... - - On the other hand, if we got some data then we can display it in a debug - message for everyone to see. - */ - switch (this->peer ().recv (_rdbuf, _rdbuf_len)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf)); - } - - return 0; -} -</pre> -<HR WIDTH="100%"> - -<P>That's the last of the C++ code. On the final two pages I'll -go over the Makefile and a short perl script I wrote to "assist" the -Makefile. Please... Continue... - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/page06.html b/docs/tutorials/005/page06.html deleted file mode 100644 index 95a341cf0ea..00000000000 --- a/docs/tutorials/005/page06.html +++ /dev/null @@ -1,195 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="Billy Quinn"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Before we go, I wanted you to see the <A HREF="Makefile">Makefile</A>. - -<P> -<HR WIDTH="100%"> -<BR> -<UL><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> -<BR><FONT FACE="Arial,Helvetica"># -$Id$</FONT> -<BR><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> - -<P><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> -<BR><FONT FACE="Arial,Helvetica"># -Local macros</FONT> -<BR><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> - -<P><FONT FACE="Arial,Helvetica"># You can generally find a Makefile in -the ACE examples, tests or the library</FONT> -<BR><FONT FACE="Arial,Helvetica"># itself that will satisfy our application -needs. This one was taken from</FONT> -<BR><FONT FACE="Arial,Helvetica"># one of the examples.</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Define the name of the binary we want to create. There has to be</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# a CPP file $(BIN).cpp but it doesn't necessarily have to have your</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# main() in it. Most of the time, though, it will.</FONT> -<BR><FONT FACE="Arial,Helvetica">BIN = server</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Few applications will have a single source file. We use the FILES</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# macro to build up a list of additional files to compile. Notice</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# that we leave off the extension just as with BIN</FONT> -<BR><FONT FACE="Arial,Helvetica">FILES =</FONT> -<BR><FONT FACE="Arial,Helvetica">FILES += client_handler</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# The BUILD macro is used by the ACE makefiles. Basically, it tells</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# the system what to build. I don't really know what VBIN is other</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# than it is constructed from the value of BIN. Just go with it...</FONT> -<BR><FONT FACE="Arial,Helvetica">BUILD = $(VBIN)</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Here we use some GNU make extensions to build the SRC macro. Basically,</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# we're just adding .cpp to the value of BIN and for each entry of the</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# FILES macro.</FONT> -<BR><FONT FACE="Arial,Helvetica">SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix -.cpp,$(FILES))</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# This is used by my Indent target below. It's not a part of standard</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# ACE and you don't need it yourself.</FONT> -<BR><FONT FACE="Arial,Helvetica">HDR = *.h</FONT> - -<P><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> -<BR><FONT FACE="Arial,Helvetica"># -Include macros and targets</FONT> -<BR><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# This is where the real power lies! These included makefile components</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# are similar to the C++ templates in ACE. That is, they do a tremendous</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# amount of work for you and all you have to do is include them.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# As a matter of fact, in our project, I created a single file named</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# "app.mk" that includes all of these. Our project makefiles then -just</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# need to include app.mk to get everything they need.</FONT> - -<P><FONT FACE="Arial,Helvetica">include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU</FONT> -<BR><FONT FACE="Arial,Helvetica">include $(ACE_ROOT)/include/makeinclude/macros.GNU</FONT> -<BR><FONT FACE="Arial,Helvetica">include $(ACE_ROOT)/include/makeinclude/rules.common.GNU</FONT> -<BR><FONT FACE="Arial,Helvetica">include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU</FONT> -<BR><FONT FACE="Arial,Helvetica">include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU</FONT> -<BR><FONT FACE="Arial,Helvetica">include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU</FONT> -<BR><FONT FACE="Arial,Helvetica">include $(ACE_ROOT)/include/makeinclude/rules.local.GNU</FONT> - -<P><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> -<BR><FONT FACE="Arial,Helvetica"># -Local targets</FONT> -<BR><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Sometimes I like to reformat my code to make it more readable. -This is</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# more useful for the comments than anything else. Unfortunately, -the</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# "indent" program doesn't quite grok C++ so I have to post-process it's</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# output just a bit.</FONT> -<BR><FONT FACE="Arial,Helvetica">Indent : #</FONT> -<BR><FONT FACE="Arial,Helvetica"> -for i in $(SRC) $(HDR) ; do \</FONT> -<BR><FONT FACE="Arial,Helvetica"> -indent -npsl -l80 -fca -fc1 -cli0 -cdb < $$i | \</FONT> -<BR><FONT FACE="Arial,Helvetica"> -sed -e 's/: :/::/g' \</FONT> -<BR><FONT FACE="Arial,Helvetica"> --e 's/^.*\(public:\)/\1/' \</FONT> -<BR><FONT FACE="Arial,Helvetica"> --e 's/^.*\(protected:\)/\1/' \</FONT> -<BR><FONT FACE="Arial,Helvetica"> --e 's/^.*\(private:\)/\1/' \</FONT> -<BR><FONT FACE="Arial,Helvetica"> --e 's/:\(public\)/ : \1/' \</FONT> -<BR><FONT FACE="Arial,Helvetica"> --e 's/:\(protected\)/ : \1/' \</FONT> -<BR><FONT FACE="Arial,Helvetica"> --e 's/:\(private\)/ : \1/' \</FONT> -<BR><FONT FACE="Arial,Helvetica"> -> $$i~ ;\</FONT> -<BR><FONT FACE="Arial,Helvetica"> -mv $$i~ $$i ;\</FONT> -<BR><FONT FACE="Arial,Helvetica"> -done</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# One of the targets in the ACE makefiles is "depend". It will invoke</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# your compiler in a way that will generate a list of dependencies for</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# you. This is a great thing! Unfortunately, it puts all of -that mess</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# directly into the Makefile. I prefer my Makefile to stay clean -and</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# uncluttered. The perl script referenced here pulls the dependency</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# stuff back out of the Makefile and into a file ".depend" which we then</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# include just like the makefile components above.</FONT> -<BR><FONT FACE="Arial,Helvetica">Depend : depend</FONT> -<BR><FONT FACE="Arial,Helvetica"> -perl fix.Makefile</FONT> -<BR><FONT FACE="Arial,Helvetica"> </FONT> -<BR><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> -<BR><FONT FACE="Arial,Helvetica"># -Dependencies</FONT> -<BR><FONT FACE="Arial,Helvetica">#----------------------------------------------------------------------------</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Don't put anything below here. Between the "depend" target and -fix.Makefile</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# it's guaranteed to be lost!</FONT> - -<P><FONT FACE="Arial,Helvetica"> -# This is inserted by the fix.Makefile script</FONT> -<BR><FONT FACE="Arial,Helvetica">include .depend</FONT></UL> - -<HR WIDTH="100%"> - -<P>Remember, make wants to see tabs leading all of the directives. -If you do a cut/paste job you'll need to convert all leading spaces to -tabs or make will be very unhappy with you. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page07.html">Continue This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/page07.html b/docs/tutorials/005/page07.html deleted file mode 100644 index 069f94be956..00000000000 --- a/docs/tutorials/005/page07.html +++ /dev/null @@ -1,123 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="Billy Quinn"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>And last (and probably least) is the <A HREF="fix.Makefile">perl script</A> -that pulls the dependency stuff out of Makefile and into .depend. - -<P> -<HR WIDTH="100%"> -<BR> <FONT FACE="Arial,Helvetica">#!/usr/bin/perl</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Open the Makefile that has been mangled by 'make depend'</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# and suck it into a perl array.</FONT> -<BR><FONT FACE="Arial,Helvetica">open(IF,"<Makefile") || die;</FONT> -<BR><FONT FACE="Arial,Helvetica">@makefile = <IF>;</FONT> -<BR><FONT FACE="Arial,Helvetica">close(IF);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Now open our .depend file and a temporary Makefile.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# We'll split the original Makefile between these two.</FONT> -<BR><FONT FACE="Arial,Helvetica">open(DF,">.depend") || die;</FONT> -<BR><FONT FACE="Arial,Helvetica">open(MF,">Makefile.tmp") || die;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -# For each line we read out of the original file...</FONT> -<BR><FONT FACE="Arial,Helvetica">foreach (@makefile) {</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -# If we're into the dependency section, write the line</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# into the .depend file.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -#</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( $depend ) {</FONT> -<BR><FONT FACE="Arial,Helvetica"> -print DF $_;</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT> -<BR><FONT FACE="Arial,Helvetica"> -else {</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# If we haven't gotten to the dependency section yet</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# then see if the current line is the separator that</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# "make depend" causes to be inserted.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -#</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( m/^\Q# DO NOT DELETE THIS LINE -- g++dep uses it.\E/ ) {</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -# If so, change our "mode" and skip this line.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -++$depend;</FONT> -<BR><FONT FACE="Arial,Helvetica"> -next;</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Also skip the "include .depend" that we insert. If we</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# don't do this, it is possible to have a bunch of these</FONT> -<BR><FONT FACE="Arial,Helvetica"> -# inserted into the output when we read an unmangled Makefile</FONT> -<BR><FONT FACE="Arial,Helvetica"> -next if( m/^include .depend/ );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -# Print the non-dependency info to the temporary Makefile</FONT> -<BR><FONT FACE="Arial,Helvetica"> -print MF $_;</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"># Tell our new Makefile to include the -dependency file</FONT> -<BR><FONT FACE="Arial,Helvetica">print MF "include .depend\n";</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"># Close the two output files...</FONT> -<BR><FONT FACE="Arial,Helvetica">close(DF);</FONT> -<BR><FONT FACE="Arial,Helvetica">close(MF);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"># Unlink (remove) the original Makefile -and rename our</FONT> -<BR><FONT FACE="Arial,Helvetica"># temporary file. There's obviously -room for error checking</FONT> -<BR><FONT FACE="Arial,Helvetica"># here but we've got the Makefile checked -into some revision</FONT> -<BR><FONT FACE="Arial,Helvetica"># control system anyway. Don't we?</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">unlink("Makefile");</FONT> -<BR><FONT FACE="Arial,Helvetica">rename("Makefile.tmp","Makefile");</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">exit(0);</FONT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page08.html">Continue This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/page08.html b/docs/tutorials/005/page08.html deleted file mode 100644 index 6cc18602049..00000000000 --- a/docs/tutorials/005/page08.html +++ /dev/null @@ -1,53 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="Billy Quinn"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 005</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 005</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>That's it for Tutorial 5. In this tutorial we've built a single-threaded -reactor-based server. We've done a couple of things that aren't exactly -necessary for such an implementation but I plan to build on that as -we explore two other concurrency strategies: thread per connection -and thread pool. - -<P>For reference, here's the file list again: -<UL> -<LI> -<A HREF="Makefile">Makefile</A></LI> - -<LI> -<A HREF="client_acceptor.h">client_acceptor.h</A></LI> - -<LI> -<A HREF="client_handler.cpp">client_handler.cpp</A></LI> - -<LI> -<A HREF="client_handler.h">client_handler.h</A></LI> - -<LI> -<A HREF="server.cpp">server.cpp</A></LI> - -<LI> -<A HREF="fix.Makefile">fix.Makefile</A></LI> -</UL> - - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/005/server.brk b/docs/tutorials/005/server.brk deleted file mode 100644 index ba3d878a1da..00000000000 --- a/docs/tutorials/005/server.brk +++ /dev/null @@ -1,154 +0,0 @@ - -#include "ace/Acceptor.h" -#include "ace/SOCK_Acceptor.h" -#include "ace/Reactor.h" -#include "ace/Thread.h" - - -ACE_Reactor * g_reactor; - -static sig_atomic_t finished = 0; - -class Logging_Handler; - -extern "C" void handler (int) { finished = 1; } - - - -class Reactor_Derived : public ACE_Reactor -{ - -public : - Reactor_Derived() : () - { - counter = 0; - } - - virtual ~Reactor_Derived() - { - cout << "*****Calling the reactor destructor*****" << endl; - } - -private : - friend class Logging_Handler; - - // counter is used to keep track of the number of service handlers - // registered with this reactor (Surely theres a better way ;-) - int counter; -}; - -class Logging_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -{ - -public: - - Logging_Handler (void) { }; - - virtual void destroy (void) - { - if (this->thread_reactorP->remove_handler(this, - ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL) == -1 - ) - ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t remove service from reactor\n"), -1); - - // Decrement the handler tracking variable in the reactor to - // indicate this service handler has terminated - --thread_reactorP->counter; - - this->peer ().close (); - delete this; - } - - static void *run_thread(Logging_Handler *this_) - { - Reactor_Derived thread_reactor; - - this_->thread_reactorP = &thread_reactor; - - // Increment our handler counter to account for this service handler - ++thread_reactor.counter; - - if (thread_reactor.register_handler(this_, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR,"can'(%P|%t) t register with reactor\n"), -1); - - while( thread_reactor.counter > 0 ) - { - // If thread_reactor.counter = 0 then we have no more service - // handlers connected to the reactor. We set a timeout value - // of 1 second so that the handle_events loop break out every - // second to check on the count ( because of it blocking - // even when there are no connections we need to do this) - thread_reactor.handle_events(ACE_Time_Value(1,0)); - } - } - - virtual int open (void *) - { - ACE_Thread::spawn(&Logging_Handler::run_thread,this); - return 0; - } - - virtual int close (u_long) - { - this->destroy (); - return 0; - } - -protected: - - virtual int handle_input (ACE_HANDLE) - { - char buf[128]; - memset(buf,0,sizeof(buf)); - - switch( this->peer().recv(buf,sizeof buf) ) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%p|%t) from client : %s",buf)); - } - - return 0; - } - - -private: - Reactor_Derived *thread_reactorP; -}; - - -typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Logging_Acceptor; - - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int argc, char *argv[]) -{ - g_reactor = new ACE_Reactor; - - // Acceptor factory. - Logging_Acceptor peer_acceptor; - - if (peer_acceptor.open (ACE_INET_Addr (PORT)) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - - else if (g_reactor->register_handler (&peer_acceptor, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1); - - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - // Run forever, performing logging service. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n")); - - // Perform logging service until QUIT_HANDLER receives SIGINT. - while ( !finished ) - g_reactor->handle_events (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n")); - - return 0; -} diff --git a/docs/tutorials/005/server.cpp b/docs/tutorials/005/server.cpp deleted file mode 100644 index ee46a9d2b57..00000000000 --- a/docs/tutorials/005/server.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// $Id$ - -/* - We try to keep main() very simple. One of the ways we do that is to push - much of the complicated stuff into worker objects. In this case, we only - need to include the acceptor header in our main source file. We let it - worry about the "real work". - */ - -#include "client_acceptor.h" - -/* - As before, we create a simple signal handler that will set our finished - flag. There are, of course, more elegant ways to handle program shutdown - requests but that isn't really our focus right now, so we'll just do the - easiest thing. - */ - -static sig_atomic_t finished = 0; -extern "C" void handler (int) -{ - finished = 1; -} - -/* - A server has to listen for clients at a known TCP/IP port. The default ACE - port is 10002 (at least on my system) and that's good enough for what we - want to do here. Obviously, a more robust application would take a command - line parameter or read from a configuration file or do some other clever - thing. Just like the signal handler above, though, that's what we want to - focus on, so we're taking the easy way out. - */ - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* - Finally, we get to main. Some C++ compilers will complain loudly if your - function signature doesn't match the prototype. Even though we're not - going to use the parameters, we still have to specify them. - */ - -int main (int argc, char *argv[]) -{ -/* - In our earlier servers, we used a global pointer to get to the reactor. I've - never really liked that idea, so I've moved it into main() this time. When - we get to the Client_Handler object you'll see how we manage to get a - pointer back to this reactor. - */ - ACE_Reactor reactor; - - /* - The acceptor will take care of letting clients connect to us. It will - also arrange for a Client_Handler to be created for each new client. - Since we're only going to listen at one TCP/IP port, we only need one - acceptor. If we wanted, though, we could create several of these and - listen at several ports. (That's what we would do if we wanted to rewrite - inetd for instance.) - */ - Client_Acceptor peer_acceptor; - - /* - Create an ACE_INET_Addr that represents our endpoint of a connection. We - then open our acceptor object with that Addr. Doing so tells the acceptor - where to listen for connections. Servers generally listen at "well known" - addresses. If not, there must be some mechanism by which the client is - informed of the server's address. - - Note how ACE_ERROR_RETURN is used if we fail to open the acceptor. This - technique is used over and over again in our tutorials. - */ - if (peer_acceptor.open (ACE_INET_Addr (PORT), &reactor) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - - /* - Here, we know that the open was successful. If it had failed, we would - have exited above. A nice side-effect of the open() is that we're already - registered with the reactor we provided it. - */ - - /* - Install our signal handler. You can actually register signal handlers - with the reactor. You might do that when the signal handler is - responsible for performing "real" work. Our simple flag-setter doesn't - justify deriving from ACE_Event_Handler and providing a callback function - though. - */ - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - /* - Like ACE_ERROR_RETURN, the ACE_DEBUG macro gets used quite a bit. It's a - handy way to generate uniform debug output from your program. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n")); - - /* - This will loop "forever" invoking the handle_events() method of our - reactor. handle_events() watches for activity on any registered handlers - and invokes their appropriate callbacks when necessary. Callback-driven - programming is a big thing in ACE, you should get used to it. If the - signal handler catches something, the finished flag will be set and we'll - exit. Conveniently enough, handle_events() is also interrupted by signals - and will exit back to the while() loop. (If you want your event loop to - not be interrupted by signals, checkout the <i>restart</i> flag on the - open() method of ACE_Reactor if you're interested.) - */ - while (!finished) - reactor.handle_events (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server daemon\n")); - - return 0; -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/docs/tutorials/006/006.dsp b/docs/tutorials/006/006.dsp deleted file mode 100644 index fe6c488995d..00000000000 --- a/docs/tutorials/006/006.dsp +++ /dev/null @@ -1,112 +0,0 @@ -# Microsoft Developer Studio Project File - Name="006" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=006 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "006.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "006.mak" CFG="006 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "006 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "006 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "006 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "006 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "006 - Win32 Release"
-# Name "006 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\client_handler.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\client_acceptor.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\client_handler.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/006/Makefile b/docs/tutorials/006/Makefile deleted file mode 100644 index 53fe1f26bff..00000000000 --- a/docs/tutorials/006/Makefile +++ /dev/null @@ -1,99 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -# You can generally find a Makefile in the ACE examples, tests or the library -# itself that will satisfy our application needs. This one was taken from -# one of the examples. - - # Define the name of the binary we want to create. There has to be - # a CPP file $(BIN).cpp but it doesn't necessarily have to have your - # main() in it. Most of the time, though, it will. -BIN = server - - # Few applications will have a single source file. We use the FILES - # macro to build up a list of additional files to compile. Notice - # that we leave off the extension just as with BIN -FILES = -FILES += client_handler - - # The BUILD macro is used by the ACE makefiles. Basically, it tells - # the system what to build. I don't really know what VBIN is other - # than it is constructed from the value of BIN. Just go with it... -BUILD = $(VBIN) - - # Here we use some GNU make extensions to build the SRC macro. Basically, - # we're just adding .cpp to the value of BIN and for each entry of the - # FILES macro. -SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix .cpp,$(FILES)) - - # This is used by my Indent target below. It's not a part of standard - # ACE and you don't need it yourself. -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - - # This is where the real power lies! These included makefile components - # are similar to the C++ templates in ACE. That is, they do a tremendous - # amount of work for you and all you have to do is include them. - # As a matter of fact, in our project, I created a single file named - # "app.mk" that includes all of these. Our project makefiles then just - # need to include app.mk to get everything they need. - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - - # Sometimes I like to reformat my code to make it more readable. This is - # more useful for the comments than anything else. Unfortunately, the - # "indent" program doesn't quite grok C++ so I have to post-process it's - # output just a bit. -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - - # One of the targets in the ACE makefiles is "depend". It will invoke - # your compiler in a way that will generate a list of dependencies for - # you. This is a great thing! Unfortunately, it puts all of that mess - # directly into the Makefile. I prefer my Makefile to stay clean and - # uncluttered. The perl script referenced here pulls the dependency - # stuff back out of the Makefile and into a file ".depend" which we then - # include just like the makefile components above. -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! - - # This is inserted by the fix.Makefile script -include .depend diff --git a/docs/tutorials/006/client_acceptor.h b/docs/tutorials/006/client_acceptor.h deleted file mode 100644 index 2318b6adacd..00000000000 --- a/docs/tutorials/006/client_acceptor.h +++ /dev/null @@ -1,85 +0,0 @@ - -// $Id$ - -#ifndef CLIENT_ACCEPTOR_H -#define CLIENT_ACCEPTOR_H - -/* - The ACE_Acceptor<> template lives in the ace/Acceptor.h header file. You'll - find a very consitent naming convention between the ACE objects and the - headers where they can be found. In general, the ACE object ACE_Foobar will - - - be found in ace/Foobar.h. - */ - -#include "ace/Acceptor.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - Since we want to work with sockets, we'll need a SOCK_Acceptor to allow the - clients to connect to us. - */ -#include "ace/SOCK_Acceptor.h" - -/* - The Client_Handler object we develop will be used to handle clients once - they're connected. The ACE_Acceptor<> template's first parameter requires - such an object. In some cases, you can get by with just a forward - declaration on the class, in others you have to have the whole thing. - */ -#include "client_handler.h" - -/* - Parameterize the ACE_Acceptor<> such that it will listen for socket - connection attempts and create Client_Handler objects when they happen. In - Tutorial 001, we wrote the basic acceptor logic on our own before we - realized that ACE_Acceptor<> was available. You'll get spoiled using the - ACE templates because they take away a lot of the tedious details! - */ -typedef ACE_Acceptor < Client_Handler, ACE_SOCK_ACCEPTOR > Client_Acceptor_Base; - -/* - Here, we use the parameterized ACE_Acceptor<> as a baseclass for our customized - Client_Acceptor object. I've done this so that we can provide it with our choice - of concurrency strategies when the object is created. Each Client_Handler it - creates will use this information to determine how to act. If we were going - to create a system that was always thread-per-connection, we would not have - bothered to extend Client_Acceptor. - */ -class Client_Acceptor : public Client_Acceptor_Base -{ -public: - /* - This is always a good idea. If nothing else, it makes your code more - orthogonal no matter what baseclasses your objects have. - */ - typedef Client_Acceptor_Base inherited; - - /* - Construct the object with the concurrency strategy. Since this tutorial - is focused on thread-per-connection, we make that the default. We could - have chosen to omitt the default and populate it in main() instead. - */ - Client_Acceptor( int _thread_per_connection = 1 ) - : thread_per_connection_(_thread_per_connection) - { - } - - /* - Return the value of our strategy flag. This is used by the Client_Handler - to decide how to act. If 'true' then the handler will behave in a - thread-per-connection manner. - */ - int thread_per_connection(void) - { return this->thread_per_connection_; } - -protected: - int thread_per_connection_; - -}; - -#endif // CLIENT_ACCEPTOR_H diff --git a/docs/tutorials/006/client_handler.cpp b/docs/tutorials/006/client_handler.cpp deleted file mode 100644 index ad254f3f130..00000000000 --- a/docs/tutorials/006/client_handler.cpp +++ /dev/null @@ -1,307 +0,0 @@ - -// $Id$ - -/* - In client_handler.h I alluded to the fact that we'll mess around with a - Client_Acceptor pointer. To do so, we need the Client_Acceptor object - declaration. - - We know that including client_handler.h is redundant because - client_acceptor.h includes it. Still, the sentry prevents double-inclusion - from causing problems and it's sometimes good to be explicit about what - we're using. - - On the other hand, we don't directly include any ACE header files here. - */ -#include "client_acceptor.h" -#include "client_handler.h" - -/* - Our constructor doesn't do anything. That's generally a good idea. Unless - you want to start throwing exceptions, there isn't a really good way to - indicate that a constructor has failed. If I had my way, I'd have a boolean - return code from it that would cause new to return 0 if I failed. Oh - well... - */ -Client_Handler::Client_Handler (void) -{ -} - -/* - Our destructor doesn't do anything either. That is also by design. - Remember, we really want folks to use destroy() to get rid of us. If that's - so, then there's nothing left to do when the destructor gets invoked. - */ -Client_Handler::~Client_Handler (void) -{ -} - -/* - The much talked about destroy() method! The reason I keep going on about - this is because it's just a Bad Idea (TM) to do real work inside of a - destructor. Although this method is void, it really should return - int so that it can tell the caller there was a problem. Even as - void you could at least throw an exception which you would never want - to do in a destructor. - */ -void Client_Handler::destroy (void) -{ - /* - Tell the reactor to forget all about us. Notice that we use the same args - here that we use in the open() method to register ourselves. In addition, - we use the DONT_CALL flag to prevent handle_close() being called. Since we - likely got here due to handle_close(), that could cause a bit of nasty - recursion! - */ - this->reactor ()->remove_handler (this, - ACE_Event_Handler:: READ_MASK | ACE_Event_Handler::DONT_CALL); - - /* - This is how we're able to tell folks not to use delete. By - deleting our own instance, we take care of memory leaks after ensuring - that the object is shut down correctly. - */ - delete this; -} - -/* - As mentioned before, the open() method is called by the Client_Acceptor when - a new client connection has been accepted. The Client_Acceptor instance - pointer is cast to a void* and given to us here. We'll use that to avoid - some global data... - */ -int Client_Handler::open (void *_acceptor) -{ - /* - We need this to store the address of the client that we are now connected - to. We'll use it later to display a debug message. - */ - ACE_INET_Addr addr; - - /* - Our ACE_Svc_Handler baseclass gives us the peer() method as a way to - access our underlying ACE_SOCK_Stream. On that object, we can invoke the - get_remote_addr() method to get get an ACE_INET_Addr having our client's - address information. As with most ACE methods, we'll get back (and return) - a -1 if there was any kind of error. Once we have the ACE_INET_Addr, we - can query it to find out the clien's host name, TCP/IP address, TCP/IP - port value and so forth. One word of warning: the get_host_name() - method of ACE_INET_Addr may return you an empty string if your name server - can't resolve it. On the other hand, get_host_addr() will always give you - the dotted-decimal string representing the TCP/IP address. - */ - if (this->peer ().get_remote_addr (addr) == -1) - { - return -1; - } - - /* - Convert the void* to a Client_Acceptor*. You should probably use those - fancy new C++ cast operators but I can never remember how/when to do so. - Since you can cast just about anything around a void* without compiler - warnings be very sure of what you're doing when you do this kind of thing. - That's where the new-style cast operators can save you. - */ - Client_Acceptor *acceptor = (Client_Acceptor *) _acceptor; - - /* - Our Client_Acceptor is constructed with a concurrency strategy. Here, we - go back to it to find out what that strategy was. If thread-per-connection - was selected then we simply activate a thread for ourselves and exit. Our - svc() method will then begin executing in that thread. - - If we are told to use the single-threaded strategy, there is no difference - between this and the Tutorial 5 implementation. - */ - if( acceptor->thread_per_connection() ) - { - return this->activate(); - } - - /* - Our reactor reference will be set when we register ourselves but I decided - to go ahead and set it here. No good reason really... - */ - this->reactor (acceptor->reactor ()); - - /* - If we managed to get the client's address then we're connected to a real - and valid client. I suppose that in some cases, the client may connect - and disconnect so quickly that it is invalid by the time we get here. In - any case, the test above should always be done to ensure that the - connection is worth keeping. - - Now, regiser ourselves with a reactor and tell that reactor that we want - to be notified when there is something to read. Remember, we took our - reactor value from the acceptor which created us in the first place. - Since we're exploring a single-threaded implementation, this is the - correct thing to do. - */ - if (this->reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - } - - /* - Here, we use the ACE_INET_Addr object to print a message with the name of - the client we're connected to. Again, it is possible that you'll get an - empty string for the host name if your DNS isn't configured correctly or - if there is some other reason that a TCP/IP addreess cannot be converted - into a host name. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ())); - - /* - Always return zero on success. - */ - return 0; -} - -/* - As mentioned in the header, the typical way to close an object in a threaded - context is to invoke it's close() method. Since we already have a handle_close() - method built to cleanup after us, we'll just forward the request on to that - object. - */ -int Client_Handler::close(u_long flags) -{ - /* - We use the destroy() method to clean up after ourselves. - That will take care of removing us from the reactor and then - freeing our memory. - */ - this->destroy(); - - /* - Don't forward the close() to the baseclass! handle_close() above has - already taken care of delete'ing. Forwarding close() would cause that - to happen again and things would get really ugly at that point! - */ - return 0; -} - -/* - In the open() method, we registered with the reactor and requested to be - notified when there is data to be read. When the reactor sees that activity - it will invoke this handle_input() method on us. As I mentioned, the _handle - parameter isn't useful to us but it narrows the list of methods the reactor - has to worry about and the list of possible virtual functions we would have - to override. - */ -int Client_Handler::handle_input (ACE_HANDLE _handle) -{ - /* - Some compilers don't like it when you fail to use a parameter. This macro - will keep 'em quiet for you. - */ - ACE_UNUSED_ARG (_handle); - - /* - Now, we create and initialize a buffer for receiving the data. Since this - is just a simple test app, we'll use a small buffer size. - */ - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the process() method with a pointer to our data area. We'll let - that method worry about interfacing with the data. You might choose to go - ahead and read the data and then pass the result to process(). However, - application logic may require that you read a few bytes to determine what - else to read... It's best if we push that all into the application-logic - level. - */ - return this->process (buf, sizeof (buf)); -} - -/* - If we return -1 out of handle_input() or if the reactor sees other problems - with us then handle_close() will be called. The reactor framework - will take care of removing us (due to the -1), so we don't need to - use the destroy() method. Instead, we just delete ourselves directly. - */ -int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask) -{ - ACE_UNUSED_ARG (_handle); - ACE_UNUSED_ARG (_mask); - - this->destroy (); - return 0; -} - -/* - The ACE_Svc_Handler<> is ultimately derived from ACE_Task<>. If you want to - create a multi-threaded application, these are your tools! Simply override - the svc() method in your derivative and arrange for your activate() method - to be called. The svc() method then executes in the new thread. - */ -int Client_Handler::svc(void) -{ - /* - Like handle_input(), we create a buffer for loading the data. Doing so - in handle_input() doesn't help any but there is a small performance increase - by doing this here: the buffer is created once when the thread is created - instead of for each invocation of process(). - */ - char buf[128]; - - // Forever... - while( 1 ) - { - // Clean the buffer... - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the proces() method to read and process the data. This is - exactly the way it is used by handle_input(). That's the reason I - created process() in the first place: so that it can be used in either - concurrency strategy. Since process() has all of our application-level - logic, it's nice that it doesn't have to change when we decide to go - multi-threaded. - - Notice that since the recv() method call in process() blocks until - there is data ready, this thread doesn't consume any CPU time until - there is actually data sent from the client. - */ - if( this->process(buf,sizeof(buf)) == -1 ) - { - return(-1); - } - } - - return(0); -} - -/* - And, at last, we get to the application-logic level. Out of everything - we've done so far, this is the only thing that really has anything to do - with what your application will do. In this method we will read and process - the client's data. In a real appliation, you will probably have a bit more - in main() to deal with command line options but after that point, all of the - action takes place here. - */ -int Client_Handler::process (char *_rdbuf, int _rdbuf_len) -{ - /* - Using the buffer provided for us, we read the data from the client. If - there is a read error (eg -- recv() returns -1) then it's a pretty good - bet that the connection is gone. Likewise, if we read zero bytes then - something wrong has happened. The reactor wouldn't have called us if - there wasn't some kind of read activity but there wouldn't be activity if - there were no bytes to read... - - On the other hand, if we got some data then we can display it in a debug - message for everyone to see. - */ - switch (this->peer ().recv (_rdbuf, _rdbuf_len)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf)); - } - - return 0; -} diff --git a/docs/tutorials/006/client_handler.h b/docs/tutorials/006/client_handler.h deleted file mode 100644 index c1c1d534a32..00000000000 --- a/docs/tutorials/006/client_handler.h +++ /dev/null @@ -1,130 +0,0 @@ - -// $Id$ - -#ifndef CLIENT_HANDLER_H -#define CLIENT_HANDLER_H - -/* - Our client handler must exist somewhere in the ACE_Event_Handler object - hierarchy. This is a requirement of the ACE_Reactor because it maintains - ACE_Event_Handler pointers for each registered event handler. You could - derive our Client_Handler directly from ACE_Event_Handler but you still have - to have an ACE_SOCK_Stream for the actually connection. With a direct - derivative of ACE_Event_Handler, you'll have to contain and maintain an - ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a - derivative of ACE_Event_Handler) some of those details are handled for you. - - */ - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" - -/* - Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<> - interface as well. That's what the ACE_NULL_SYNCH parameter below is all - about. If our Client_Acceptor has chosen thread-per-connection then our - open() method will activate us into a thread. At that point, our svc() - method will execute. We still don't take advantage of the thiings - ACE_NULL_SYNCH exists for but stick around for Tutorial 7 and pay special - attention to the Thread_Pool object there for an explanation. - */ -class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - typedef ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited; - - // Constructor... - Client_Handler (void); - - /* - The destroy() method is our preferred method of destruction. We could - have overloaded the delete operator but that is neither easy nor - intuitive (at least to me). Instead, we provide a new method of - destruction and we make our destructor protected so that only ourselves, - our derivatives and our friends can delete us. It's a nice - compromise. - */ - void destroy (void); - - /* - Most ACE objects have an open() method. That's how you make them ready - to do work. ACE_Event_Handler has a virtual open() method which allows us - to create this overrride. ACE_Acceptor<> will invoke this method after - creating a new Client_Handler when a client connects. Notice that the - parameter to open() is a void*. It just so happens that the pointer - points to the acceptor which created us. You would like for the parameter - to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that - would tie it too closely to the ACE_Acceptor<> set of objects. In our - definition of open() you'll see how we get around that. - */ - int open (void *_acceptor); - - /* - When an ACE_Task<> object falls out of the svc() method, the framework - will call the close() method. That's where we want to cleanup ourselves - if we're running in either thread-per-connection or thread-pool mode. - */ - int close(u_long flags = 0); - - /* - When there is activity on a registered handler, the handle_input() method - of the handler will be invoked. If that method returns an error code (eg - -- -1) then the reactor will invoke handle_close() to allow the object to - clean itself up. Since an event handler can be registered for more than - one type of callback, the callback mask is provided to inform - handle_close() exactly which method failed. That way, you don't have to - maintain state information between your handle_* method calls. The _handle - parameter is explained below... - As a side-effect, the reactor will also invoke remove_handler() - for the object on the mask that caused the -1 return. This means - that we don't have to do that ourselves! - */ - virtual int handle_close (ACE_HANDLE _handle = ACE_INVALID_HANDLE, - ACE_Reactor_Mask _mask = ACE_Event_Handler::ALL_EVENTS_MASK ); - -protected: - - /* - If the Client_Acceptor which created us has chosen a thread-per-connection - strategy then our open() method will activate us into a dedicate thread. - The svc() method will then execute in that thread performing some of the - functions we used to leave up to the reactor. - */ - int svc(void); - - /* - When we register with the reactor, we're going to tell it that we want to - be notified of READ events. When the reactor sees that there is read - activity for us, our handle_input() will be invoked. The _handleg - provided is the handle (file descriptor in Unix) of the actual connection - causing the activity. Since we're derived from ACE_Svc_Handler<> and it - maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for - us. However, if we had been derived directly from ACE_Event_Handler, we - may have chosen not to contain the peer. In that case, the _handleg - would be important to us for reading the client's data. - */ - int handle_input (ACE_HANDLE _handle); - - /* - This has nothing at all to do with ACE. I've added this here as a worker - function which I will call from handle_input(). As promised in Tutorial 5 - I will use this now to make it easier to switch between our two possible - concurrency strategies. - */ - int process (char *_rdbuf, int _rdbuf_len); - - /* - We don't really do anything in our destructor but we've declared it to be - protected to prevent casual deletion of this object. As I said above, I - really would prefer that everyone goes through the destroy() method to get - rid of us. - */ - ~Client_Handler (void); -}; - -#endif // CLIENT_HANDLER_H diff --git a/docs/tutorials/006/fix.Makefile b/docs/tutorials/006/fix.Makefile deleted file mode 100644 index e99c194114a..00000000000 --- a/docs/tutorials/006/fix.Makefile +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/perl - - # Open the Makefile that has been mangled by 'make depend' - # and suck it into a perl array. -open(IF,"<Makefile") || die; -@makefile = <IF>; -close(IF); - - # Now open our .depend file and a temporary Makefile. - # We'll split the original Makefile between these two. -open(DF,">.depend") || die; -open(MF,">Makefile.tmp") || die; - - # For each line we read out of the original file... -foreach (@makefile) { - - # If we're into the dependency section, write the line - # into the .depend file. - # - if( $depend ) { - print DF $_; - } - else { - # If we haven't gotten to the dependency section yet - # then see if the current line is the separator that - # "make depend" causes to be inserted. - # - if( m/^\Q# DO NOT DELETE THIS LINE -- g++dep uses it.\E/ ) { - - # If so, change our "mode" and skip this line. - ++$depend; - next; - } - - # Also skip the "include .depend" that we insert. If we - # don't do this, it is possible to have a bunch of these - # inserted into the output when we read an unmangled Makefile - next if( m/^include .depend/ ); - - # Print the non-dependency info to the temporary Makefile - print MF $_; - } -} - -# Tell our new Makefile to include the dependency file -print MF "include .depend\n"; - -# Close the two output files... -close(DF); -close(MF); - -# Unlink (remove) the original Makefile and rename our -# temporary file. There's obviously room for error checking -# here but we've got the Makefile checked into some revision -# control system anyway. Don't we? - -unlink("Makefile"); -rename("Makefile.tmp","Makefile"); - -exit(0); diff --git a/docs/tutorials/006/page01.html b/docs/tutorials/006/page01.html deleted file mode 100644 index cd20f343e91..00000000000 --- a/docs/tutorials/006/page01.html +++ /dev/null @@ -1,33 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 006</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 006</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-per-connection server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In this tutorial, we're going to extend Tutorial 5 to create a thread-per-connection -server. This implementation will create a new thread for each client -which connects to us. The ACE_Reactor is still used but only for -accepting new connections. The Client_Handler objects won't be registered -with the reactor. Instead, they'll be responsible for monitoring -their peer() directly. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/006/page02.html b/docs/tutorials/006/page02.html deleted file mode 100644 index 29d4c457ff1..00000000000 --- a/docs/tutorials/006/page02.html +++ /dev/null @@ -1,205 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 006</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 006</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-per-connection server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Again, we begin with <A HREF="server.cpp">server.cpp.</A> If you -look closely you will see that the only difference between this and the -Tutorial 5 implementation is a single comment. - -<P> -<HR WIDTH="100%"><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">// $Id: server.cpp,v 1.1 1998/08/30 13:38:28 -jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> We try to keep main() very -simple. One of the ways we do that is to push</FONT> -<BR><FONT FACE="Arial,Helvetica"> much of the complicated stuff -into worker objects. In this case, we only</FONT> -<BR><FONT FACE="Arial,Helvetica"> need to include the acceptor -header in our main source file. We let it</FONT> -<BR><FONT FACE="Arial,Helvetica"> worry about the "real work".</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "client_acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> As before, we create a simple -signal handler that will set our finished</FONT> -<BR><FONT FACE="Arial,Helvetica"> flag. There are, of -course, more elegant ways to handle program shutdown</FONT> -<BR><FONT FACE="Arial,Helvetica"> requests but that isn't really -our focus right now, so we'll just do the</FONT> -<BR><FONT FACE="Arial,Helvetica"> easiest thing.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">static sig_atomic_t finished = 0;</FONT> -<BR><FONT FACE="Arial,Helvetica">extern "C" void handler (int)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> finished = 1;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> A server has to listen for -clients at a known TCP/IP port. The default ACE</FONT> -<BR><FONT FACE="Arial,Helvetica"> port is 10002 (at least on -my system) and that's good enough for what we</FONT> -<BR><FONT FACE="Arial,Helvetica"> want to do here. Obviously, -a more robust application would take a command</FONT> -<BR><FONT FACE="Arial,Helvetica"> line parameter or read from -a configuration file or do some other clever</FONT> -<BR><FONT FACE="Arial,Helvetica"> thing. Just like the -signal handler above, though, that's what we want to</FONT> -<BR><FONT FACE="Arial,Helvetica"> focus on, so we're taking -the easy way out.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Finally, we get to main. -Some C++ compilers will complain loudly if your</FONT> -<BR><FONT FACE="Arial,Helvetica"> function signature doesn't -match the prototype. Even though we're not</FONT> -<BR><FONT FACE="Arial,Helvetica"> going to use the parameters, -we still have to specify them.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">int main (int argc, char *argv[])</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> In our earlier servers, we -used a global pointer to get to the reactor. I've</FONT> -<BR><FONT FACE="Arial,Helvetica"> never really liked that idea, -so I've moved it into main() this time. When</FONT> -<BR><FONT FACE="Arial,Helvetica"> we get to the Client_Handler -object you'll see how we manage to get a</FONT> -<BR><FONT FACE="Arial,Helvetica"> pointer back to this reactor.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_Reactor reactor;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The acceptor -will take care of letting clients connect to us. It will</FONT> -<BR><FONT FACE="Arial,Helvetica"> also arrange -for a Client_Handler to be created for each new client.</FONT> -<BR><FONT FACE="Arial,Helvetica"> Since we're only -going to listen at one TCP/IP port, we only need one</FONT> -<BR><FONT FACE="Arial,Helvetica"> acceptor. -If we wanted, though, we could create several of these and</FONT> -<BR><FONT FACE="Arial,Helvetica"> listen at several -ports. (That's what we would do if we wanted to rewrite</FONT> -<BR><FONT FACE="Arial,Helvetica"> inetd for -instance.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> Client_Acceptor peer_acceptor;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Create an ACE_INET_Addr -that represents our endpoint of a connection. We</FONT> -<BR><FONT FACE="Arial,Helvetica"> then open our -acceptor object with that Addr. Doing so tells the acceptor</FONT> -<BR><FONT FACE="Arial,Helvetica"> where to listen -for connections. Servers generally listen at "well known"</FONT> -<BR><FONT FACE="Arial,Helvetica"> addresses. -If not, there must be some mechanism by which the client is</FONT> -<BR><FONT FACE="Arial,Helvetica"> informed of the -server's address.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> Note how ACE_ERROR_RETURN -is used if we fail to open the acceptor. This</FONT> -<BR><FONT FACE="Arial,Helvetica"> technique is -used over and over again in our tutorials.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> if (peer_acceptor.open (ACE_INET_Addr -(PORT), &reactor) == -1)</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_ERROR_RETURN ((LM_ERROR, -"%p\n", "open"), -1);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> As with Tutorial -5, we know that we're now registered with our reactor</FONT> -<BR><FONT FACE="Arial,Helvetica"> so we don't have -to mess with that step.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Install our signal -handler. You can actually register signal handlers</FONT> -<BR><FONT FACE="Arial,Helvetica"> with the reactor. -You might do that when the signal handler is</FONT> -<BR><FONT FACE="Arial,Helvetica"> responsible for -performing "real" work. Our simple flag-setter doesn't</FONT> -<BR><FONT FACE="Arial,Helvetica"> justify deriving -from ACE_Event_Handler and providing a callback function</FONT> -<BR><FONT FACE="Arial,Helvetica"> though.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_Sig_Action sa ((ACE_SignalHandler) -handler, SIGINT);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Like ACE_ERROR_RETURN, -the ACE_DEBUG macro gets used quite a bit. It's a</FONT> -<BR><FONT FACE="Arial,Helvetica"> handy way to -generate uniform debug output from your program.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_DEBUG ((LM_DEBUG, "(%P|%t) -starting up server daemon\n"));</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> This will loop -"forever" invoking the handle_events() method of our</FONT> -<BR><FONT FACE="Arial,Helvetica"> reactor. handle_events() -watches for activity on any registered handlers</FONT> -<BR><FONT FACE="Arial,Helvetica"> and invokes their -appropriate callbacks when necessary. Callback-driven</FONT> -<BR><FONT FACE="Arial,Helvetica"> programming is -a big thing in ACE, you should get used to it. If the</FONT> -<BR><FONT FACE="Arial,Helvetica"> signal handler -catches something, the finished flag will be set and we'll</FONT> -<BR><FONT FACE="Arial,Helvetica"> exit. Conveniently -enough, handle_events() is also interrupted by signals</FONT> -<BR><FONT FACE="Arial,Helvetica"> and will exit -back to the while() loop. (If you want your event loop to</FONT> -<BR><FONT FACE="Arial,Helvetica"> not be interrupted -by signals, checkout the <i>restart</i> flag on the</FONT> -<BR><FONT FACE="Arial,Helvetica"> open() method -of ACE_Reactor if you're interested.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> while (!finished)</FONT> -<BR><FONT FACE="Arial,Helvetica"> reactor.handle_events -();</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting -down server daemon\n"));</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> return 0;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT> - -<P> -<HR WIDTH="100%"> - -<P>Let's move along and see what happend to the Client_Acceptor. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/006/page03.html b/docs/tutorials/006/page03.html deleted file mode 100644 index b9dad643a4e..00000000000 --- a/docs/tutorials/006/page03.html +++ /dev/null @@ -1,167 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 006</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 006</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-per-connection server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In <A HREF="client_acceptor.h">client_acceptor.h</A>, we've extended -our object just a bit. The primary reason is to allow us to select -the previous single-threaded implementation or our new thread-per-connection -implementation. Client_Acceptor itself doesn't use this information -but makes it available to the Client_Handler objects it creates. -If we wanted a single-strategy implementation, we would have made no changes -to the Tutorial 5 version of this file. - -<P> -<HR WIDTH="100%"> - -<P><FONT FACE="Arial,Helvetica">// $Id: client_acceptor.h,v 1.1 1998/08/30 -13:38:27 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#ifndef CLIENT_ACCEPTOR_H</FONT> -<BR><FONT FACE="Arial,Helvetica">#define CLIENT_ACCEPTOR_H</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The ACE_Acceptor<> template -lives in the ace/Acceptor.h header file. You'll</FONT> -<BR><FONT FACE="Arial,Helvetica"> find a very consitent naming -convention between the ACE objects and the</FONT> -<BR><FONT FACE="Arial,Helvetica"> headers where they can be -found. In general, the ACE object ACE_Foobar will</FONT> -<BR><FONT FACE="Arial,Helvetica"></FONT> <FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> be found in ace/Foobar.h.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "ace/Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Since we want to work with -sockets, we'll need a SOCK_Acceptor to allow the</FONT> -<BR><FONT FACE="Arial,Helvetica"> clients to connect to us.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "ace/SOCK_Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The Client_Handler object -we develop will be used to handle clients once</FONT> -<BR><FONT FACE="Arial,Helvetica"> they're connected. -The ACE_Acceptor<> template's first parameter requires</FONT> -<BR><FONT FACE="Arial,Helvetica"> such an object. In -some cases, you can get by with just a forward</FONT> -<BR><FONT FACE="Arial,Helvetica"> declaration on the class, -in others you have to have the whole thing.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "client_handler.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Parameterize the ACE_Acceptor<> -such that it will listen for socket</FONT> -<BR><FONT FACE="Arial,Helvetica"> connection attempts and create -Client_Handler objects when they happen. In</FONT> -<BR><FONT FACE="Arial,Helvetica"> Tutorial 001, we wrote the -basic acceptor logic on our own before we</FONT> -<BR><FONT FACE="Arial,Helvetica"> realized that ACE_Acceptor<> -was available. You'll get spoiled using the</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE templates because they -take away a lot of the tedious details!</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">typedef ACE_Acceptor < Client_Handler, -ACE_SOCK_ACCEPTOR > Client_Acceptor_Base;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Here, we use the parameterized -ACE_Acceptor<> as a baseclass for our customized</FONT> -<BR><FONT FACE="Arial,Helvetica"> Client_Acceptor object. -I've done this so that we can provide it with our choice</FONT> -<BR><FONT FACE="Arial,Helvetica"> of concurrency strategies -when the object is created. Each Client_Handler it</FONT> -<BR><FONT FACE="Arial,Helvetica"> creates will use this information -to determine how to act. If we were going</FONT> -<BR><FONT FACE="Arial,Helvetica"> to create a system that was -always thread-per-connection, we would not have</FONT> -<BR><FONT FACE="Arial,Helvetica"> bothered to extend -Client_Acceptor.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">class Client_Acceptor : public Client_Acceptor_Base</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">public:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -This is always a good idea. If nothing else, it makes your code more</FONT> -<BR><FONT FACE="Arial,Helvetica"> -orthogonal no matter what baseclasses your objects have.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -typedef Client_Acceptor_Base inherited;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Construct the object with the concurrency strategy. Since this tutorial</FONT> -<BR><FONT FACE="Arial,Helvetica"> -is focused on thread-per-connection, we make that the default. We -could</FONT> -<BR><FONT FACE="Arial,Helvetica"> -have chosen to omitt the default and populate it in main() instead.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Client_Acceptor( int _thread_per_connection = 1 )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -: thread_per_connection_(_thread_per_connection)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Return the value of our strategy flag. This is used by the Client_Handler</FONT> -<BR><FONT FACE="Arial,Helvetica"> -to decide how to act. If 'true' then the handler will behave in a</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread-per-connection manner.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int thread_per_connection(void)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{ return this->thread_per_connection_; }</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">protected:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int thread_per_connection_;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#endif // CLIENT_ACCEPTOR_H</FONT> - -<P> -<HR WIDTH="100%"> - -<P>Ok, so far we haven't done much to change our concurrency strategy. -Let's move on to the Client_Handler and see if it has changed any. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/006/page04.html b/docs/tutorials/006/page04.html deleted file mode 100644 index a203c7608a8..00000000000 --- a/docs/tutorials/006/page04.html +++ /dev/null @@ -1,167 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 006</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 006</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-per-connection server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P><A HREF="client_handler.h">client_handler.h</A> -shows a few more changes than the previous sources. The important -change is the addition of a svc() method where our connection thread will -exist. - -<P> -<HR WIDTH="100%"> - -<pre><FONT FACE="Arial,Helvetica"> -#ifndef CLIENT_HANDLER_H -#define CLIENT_HANDLER_H - -/* - Our client handler must exist somewhere in the ACE_Event_Handler object - hierarchy. This is a requirement of the ACE_Reactor because it maintains - ACE_Event_Handler pointers for each registered event handler. You could - derive our Client_Handler directly from ACE_Event_Handler but you still have - to have an ACE_SOCK_Stream for the actually connection. With a direct - derivative of ACE_Event_Handler, you'll have to contain and maintain an - ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a - derivative of ACE_Event_Handler) some of those details are handled for you. - - */ - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" - -/* - Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<> - interface as well. That's what the ACE_NULL_SYNCH parameter below is all - about. If our Client_Acceptor has chosen thread-per-connection then our - open() method will activate us into a thread. At that point, our svc() - method will execute. We still don't take advantage of the thiings - ACE_NULL_SYNCH exists for but stick around for Tutorial 7 and pay special - attention to the Thread_Pool object there for an explanation. - */ -class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - typedef ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited; - - // Constructor... - Client_Handler (void); - - /* - The destroy() method is our preferred method of destruction. We could - have overloaded the delete operator but that is neither easy nor - intuitive (at least to me). Instead, we provide a new method of - destruction and we make our destructor protected so that only ourselves, - our derivatives and our friends can delete us. It's a nice - compromise. - */ - void destroy (void); - - /* - Most ACE objects have an open() method. That's how you make them ready - to do work. ACE_Event_Handler has a virtual open() method which allows us - to create this overrride. ACE_Acceptor<> will invoke this method after - creating a new Client_Handler when a client connects. Notice that the - parameter to open() is a void*. It just so happens that the pointer - points to the acceptor which created us. You would like for the parameter - to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that - would tie it too closely to the ACE_Acceptor<> set of objects. In our - definition of open() you'll see how we get around that. - */ - int open (void *_acceptor); - - /* - When an ACE_Task<> object falls out of the svc() method, the framework - will call the close() method. That's where we want to cleanup ourselves - if we're running in either thread-per-connection or thread-pool mode. - */ - int close(u_long flags = 0); - - /* - When there is activity on a registered handler, the handle_input() method - of the handler will be invoked. If that method returns an error code (eg - -- -1) then the reactor will invoke handle_close() to allow the object to - clean itself up. Since an event handler can be registered for more than - one type of callback, the callback mask is provided to inform - handle_close() exactly which method failed. That way, you don't have to - maintain state information between your handle_* method calls. The _handle - parameter is explained below... - As a side-effect, the reactor will also invoke remove_handler() - for the object on the mask that caused the -1 return. This means - that we don't have to do that ourselves! - */ - int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask); - -protected: - - /* - If the Client_Acceptor which created us has chosen a thread-per-connection - strategy then our open() method will activate us into a dedicate thread. - The svc() method will then execute in that thread performing some of the - functions we used to leave up to the reactor. - */ - int svc(void); - - /* - When we register with the reactor, we're going to tell it that we want to - be notified of READ events. When the reactor sees that there is read - activity for us, our handle_input() will be invoked. The _handleg - provided is the handle (file descriptor in Unix) of the actual connection - causing the activity. Since we're derived from ACE_Svc_Handler<> and it - maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for - us. However, if we had been derived directly from ACE_Event_Handler, we - may have chosen not to contain the peer. In that case, the _handleg - would be important to us for reading the client's data. - */ - int handle_input (ACE_HANDLE _handle); - - /* - This has nothing at all to do with ACE. I've added this here as a worker - function which I will call from handle_input(). As promised in Tutorial 5 - I will use this now to make it easier to switch between our two possible - concurrency strategies. - */ - int process (char *_rdbuf, int _rdbuf_len); - - /* - We don't really do anything in our destructor but we've declared it to be - protected to prevent casual deletion of this object. As I said above, I - really would prefer that everyone goes through the destroy() method to get - rid of us. - */ - ~Client_Handler (void); -}; - -#endif // CLIENT_HANDLER_H -</pre> -<HR WIDTH="100%"> - -<P>So... we've added a svc() method and alluded to changes in open(). -Let's move on to the object definition and see what all the fuss is about. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/006/page05.html b/docs/tutorials/006/page05.html deleted file mode 100644 index 0b3209e8ba2..00000000000 --- a/docs/tutorials/006/page05.html +++ /dev/null @@ -1,350 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 006</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 006</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-per-connection server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P><A HREF="client_handler.cpp">client_handler.cpp</A> exposes all the -things I've been hinting at. Pay special attention to the decision -made in open() as well as the bit of cleverness in svc(). - -<P> -<HR WIDTH="100%"> - -<pre><FONT FACE="Arial,Helvetica"> -/* - In client_handler.h I alluded to the fact that we'll mess around with a - Client_Acceptor pointer. To do so, we need the Client_Acceptor object - declaration. - - We know that including client_handler.h is redundant because - client_acceptor.h includes it. Still, the sentry prevents double-inclusion - from causing problems and it's sometimes good to be explicit about what - we're using. - - On the other hand, we don't directly include any ACE header files here. - */ -#include "client_acceptor.h" -#include "client_handler.h" - -/* - Our constructor doesn't do anything. That's generally a good idea. Unless - you want to start throwing exceptions, there isn't a really good way to - indicate that a constructor has failed. If I had my way, I'd have a boolean - return code from it that would cause new to return 0 if I failed. Oh - well... - */ -Client_Handler::Client_Handler (void) -{ -} - -/* - Our destructor doesn't do anything either. That is also by design. - Remember, we really want folks to use destroy() to get rid of us. If that's - so, then there's nothing left to do when the destructor gets invoked. - */ -Client_Handler::~Client_Handler (void) -{ -} - -/* - The much talked about destroy() method! The reason I keep going on about - this is because it's just a Bad Idea (TM) to do real work inside of a - destructor. Although this method is void, it really should return - int so that it can tell the caller there was a problem. Even as - void you could at least throw an exception which you would never want - to do in a destructor. - */ -void Client_Handler::destroy (void) -{ - /* - Tell the reactor to forget all about us. Notice that we use the same args - here that we use in the open() method to register ourselves. In addition, - we use the DONT_CALL flag to prevent handle_close() being called. Since we - likely got here due to handle_close(), that could cause a bit of nasty - recursion! - */ - this->reactor ()->remove_handler (this, - ACE_Event_Handler:: READ_MASK | ACE_Event_Handler::DONT_CALL); - - /* - This is how we're able to tell folks not to use delete. By - deleting our own instance, we take care of memory leaks after ensuring - that the object is shut down correctly. - */ - delete this; -} - -/* - As mentioned before, the open() method is called by the Client_Acceptor when - a new client connection has been accepted. The Client_Acceptor instance - pointer is cast to a void* and given to us here. We'll use that to avoid - some global data... - */ -int Client_Handler::open (void *_acceptor) -{ - /* - We need this to store the address of the client that we are now connected - to. We'll use it later to display a debug message. - */ - ACE_INET_Addr addr; - - /* - Our ACE_Svc_Handler baseclass gives us the peer() method as a way to - access our underlying ACE_SOCK_Stream. On that object, we can invoke the - get_remote_addr() method to get get an ACE_INET_Addr having our client's - address information. As with most ACE methods, we'll get back (and return) - a -1 if there was any kind of error. Once we have the ACE_INET_Addr, we - can query it to find out the clien's host name, TCP/IP address, TCP/IP - port value and so forth. One word of warning: the get_host_name() - method of ACE_INET_Addr may return you an empty string if your name server - can't resolve it. On the other hand, get_host_addr() will always give you - the dotted-decimal string representing the TCP/IP address. - */ - if (this->peer ().get_remote_addr (addr) == -1) - { - return -1; - } - - /* - Convert the void* to a Client_Acceptor*. You should probably use those - fancy new C++ cast operators but I can never remember how/when to do so. - Since you can cast just about anything around a void* without compiler - warnings be very sure of what you're doing when you do this kind of thing. - That's where the new-style cast operators can save you. - */ - Client_Acceptor *acceptor = (Client_Acceptor *) _acceptor; - - /* - Our Client_Acceptor is constructed with a concurrency strategy. Here, we - go back to it to find out what that strategy was. If thread-per-connection - was selected then we simply activate a thread for ourselves and exit. Our - svc() method will then begin executing in that thread. - - If we are told to use the single-threaded strategy, there is no difference - between this and the Tutorial 5 implementation. - */ - if( acceptor->thread_per_connection() ) - { - return this->activate(); - } - - /* - Our reactor reference will be set when we register ourselves but I decided - to go ahead and set it here. No good reason really... - */ - this->reactor (acceptor->reactor ()); - - /* - If we managed to get the client's address then we're connected to a real - and valid client. I suppose that in some cases, the client may connect - and disconnect so quickly that it is invalid by the time we get here. In - any case, the test above should always be done to ensure that the - connection is worth keeping. - - Now, regiser ourselves with a reactor and tell that reactor that we want - to be notified when there is something to read. Remember, we took our - reactor value from the acceptor which created us in the first place. - Since we're exploring a single-threaded implementation, this is the - correct thing to do. - */ - if (this->reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - } - - /* - Here, we use the ACE_INET_Addr object to print a message with the name of - the client we're connected to. Again, it is possible that you'll get an - empty string for the host name if your DNS isn't configured correctly or - if there is some other reason that a TCP/IP addreess cannot be converted - into a host name. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ())); - - /* - Always return zero on success. - */ - return 0; -} - -/* - As mentioned in the header, the typical way to close an object in a threaded - context is to invoke it's close() method. Since we already have a handle_close() - method built to cleanup after us, we'll just forward the request on to that - object. - */ -int Client_Handler::close(u_long flags) -{ - /* - We use the destroy() method to clean up after ourselves. - That will take care of removing us from the reactor and then - freeing our memory. - */ - this->destroy(); - - /* - Don't forward the close() to the baseclass! handle_close() above has - already taken care of delete'ing. Forwarding close() would cause that - to happen again and things would get really ugly at that point! - */ - return 0; -} - -/* - In the open() method, we registered with the reactor and requested to be - notified when there is data to be read. When the reactor sees that activity - it will invoke this handle_input() method on us. As I mentioned, the _handle - parameter isn't useful to us but it narrows the list of methods the reactor - has to worry about and the list of possible virtual functions we would have - to override. - */ -int Client_Handler::handle_input (ACE_HANDLE _handle) -{ - /* - Some compilers don't like it when you fail to use a parameter. This macro - will keep 'em quiet for you. - */ - ACE_UNUSED_ARG (_handle); - - /* - Now, we create and initialize a buffer for receiving the data. Since this - is just a simple test app, we'll use a small buffer size. - */ - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the process() method with a pointer to our data area. We'll let - that method worry about interfacing with the data. You might choose to go - ahead and read the data and then pass the result to process(). However, - application logic may require that you read a few bytes to determine what - else to read... It's best if we push that all into the application-logic - level. - */ - return this->process (buf, sizeof (buf)); -} - -/* - If we return -1 out of handle_input() or if the reactor sees other problems - with us then handle_close() will be called. The reactor framework - will take care of removing us (due to the -1), so we don't need to - use the destroy() method. Instead, we just delete ourselves directly. - */ -int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask) -{ - ACE_UNUSED_ARG (_handle); - ACE_UNUSED_ARG (_mask); - - this->destroy (); - return 0; -} - -/* - The ACE_Svc_Handler<> is ultimately derived from ACE_Task<>. If you want to - create a multi-threaded application, these are your tools! Simply override - the svc() method in your derivative and arrange for your activate() method - to be called. The svc() method then executes in the new thread. - */ -int Client_Handler::svc(void) -{ - /* - Like handle_input(), we create a buffer for loading the data. Doing so - in handle_input() doesn't help any but there is a small performance increase - by doing this here: the buffer is created once when the thread is created - instead of for each invocation of process(). - */ - char buf[128]; - - // Forever... - while( 1 ) - { - // Clean the buffer... - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the proces() method to read and process the data. This is - exactly the way it is used by handle_input(). That's the reason I - created process() in the first place: so that it can be used in either - concurrency strategy. Since process() has all of our application-level - logic, it's nice that it doesn't have to change when we decide to go - multi-threaded. - - Notice that since the recv() method call in process() blocks until - there is data ready, this thread doesn't consume any CPU time until - there is actually data sent from the client. - */ - if( this->process(buf,sizeof(buf)) == -1 ) - { - return(-1); - } - } - - return(0); -} - -/* - And, at last, we get to the application-logic level. Out of everything - we've done so far, this is the only thing that really has anything to do - with what your application will do. In this method we will read and process - the client's data. In a real appliation, you will probably have a bit more - in main() to deal with command line options but after that point, all of the - action takes place here. - */ -int Client_Handler::process (char *_rdbuf, int _rdbuf_len) -{ - /* - Using the buffer provided for us, we read the data from the client. If - there is a read error (eg -- recv() returns -1) then it's a pretty good - bet that the connection is gone. Likewise, if we read zero bytes then - something wrong has happened. The reactor wouldn't have called us if - there wasn't some kind of read activity but there wouldn't be activity if - there were no bytes to read... - - On the other hand, if we got some data then we can display it in a debug - message for everyone to see. - */ - switch (this->peer ().recv (_rdbuf, _rdbuf_len)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf)); - } - - return 0; -} -</pre> -<HR WIDTH="100%"> - -<P>Well, that's it! After all the talk & the hype, you would -have expected it to be more difficult to create a multi-threaded server. -Surprise! It really is that easy. You still have to handle -contention issues which we haven't addressed here and that is a rather -nasty topic. Still, for the simple case, this is all you have to -do. - -<P>The next page is the last for this tutorial. Head on over there -& we'll round up the file list one last time. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/006/page06.html b/docs/tutorials/006/page06.html deleted file mode 100644 index b4ad640b25e..00000000000 --- a/docs/tutorials/006/page06.html +++ /dev/null @@ -1,52 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 006</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 006</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>On the road to a multithreaded server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>That's it for Tutorial 6. With very little effort we've managed -to extend the previous single-threaded server to an implementation which -allows runtime selection of single or multi-threaded operation. In -Tutorial 7 we'll extend that again to allow a thread-pool choice in addition -to the current two. - -<P>For reference, here's the file list again: -<UL> -<LI> -<A HREF="Makefile">Makefile</A></LI> - -<LI> -<A HREF="client_acceptor.h">client_acceptor.h</A></LI> - -<LI> -<A HREF="client_handler.cpp">client_handler.cpp</A></LI> - -<LI> -<A HREF="client_handler.h">client_handler.h</A></LI> - -<LI> -<A HREF="server.cpp">server.cpp</A></LI> - -<LI> -<A HREF="fix.Makefile">fix.Makefile</A></LI> -</UL> - - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../../tutorials">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/006/server.cpp b/docs/tutorials/006/server.cpp deleted file mode 100644 index 5195f46f8d0..00000000000 --- a/docs/tutorials/006/server.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// $Id$ - -/* - We try to keep main() very simple. One of the ways we do that is to push - much of the complicated stuff into worker objects. In this case, we only - need to include the acceptor header in our main source file. We let it - worry about the "real work". - */ - -#include "client_acceptor.h" - -/* - As before, we create a simple signal handler that will set our finished - flag. There are, of course, more elegant ways to handle program shutdown - requests but that isn't really our focus right now, so we'll just do the - easiest thing. - */ - -static sig_atomic_t finished = 0; -extern "C" void handler (int) -{ - finished = 1; -} - -/* - A server has to listen for clients at a known TCP/IP port. The default ACE - port is 10002 (at least on my system) and that's good enough for what we - want to do here. Obviously, a more robust application would take a command - line parameter or read from a configuration file or do some other clever - thing. Just like the signal handler above, though, that's what we want to - focus on, so we're taking the easy way out. - */ - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* - Finally, we get to main. Some C++ compilers will complain loudly if your - function signature doesn't match the prototype. Even though we're not - going to use the parameters, we still have to specify them. - */ - -int main (int argc, char *argv[]) -{ -/* - In our earlier servers, we used a global pointer to get to the reactor. I've - never really liked that idea, so I've moved it into main() this time. When - we get to the Client_Handler object you'll see how we manage to get a - pointer back to this reactor. - */ - ACE_Reactor reactor; - - /* - The acceptor will take care of letting clients connect to us. It will - also arrange for a Client_Handler to be created for each new client. - Since we're only going to listen at one TCP/IP port, we only need one - acceptor. If we wanted, though, we could create several of these and - listen at several ports. (That's what we would do if we wanted to rewrite - inetd for instance.) - */ - Client_Acceptor peer_acceptor; - - /* - Create an ACE_INET_Addr that represents our endpoint of a connection. We - then open our acceptor object with that Addr. Doing so tells the acceptor - where to listen for connections. Servers generally listen at "well known" - addresses. If not, there must be some mechanism by which the client is - informed of the server's address. - - Note how ACE_ERROR_RETURN is used if we fail to open the acceptor. This - technique is used over and over again in our tutorials. - */ - if (peer_acceptor.open (ACE_INET_Addr (PORT), &reactor) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - - /* - As with Tutorial 5, we know that we're now registered with our reactor - so we don't have to mess with that step. - */ - - /* - Install our signal handler. You can actually register signal handlers - with the reactor. You might do that when the signal handler is - responsible for performing "real" work. Our simple flag-setter doesn't - justify deriving from ACE_Event_Handler and providing a callback function - though. - */ - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - /* - Like ACE_ERROR_RETURN, the ACE_DEBUG macro gets used quite a bit. It's a - handy way to generate uniform debug output from your program. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n")); - - /* - This will loop "forever" invoking the handle_events() method of our - reactor. handle_events() watches for activity on any registered handlers - and invokes their appropriate callbacks when necessary. Callback-driven - programming is a big thing in ACE, you should get used to it. If the - signal handler catches something, the finished flag will be set and we'll - exit. Conveniently enough, handle_events() is also interrupted by signals - and will exit back to the while() loop. (If you want your event loop to - not be interrupted by signals, checkout the <i>restart</i> flag on the - open() method of ACE_Reactor if you're interested.) - */ - while (!finished) - reactor.handle_events (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server daemon\n")); - - return 0; -} - -#if !defined(ACE_HAS_GNU_REPO) -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ -#endif /* ACE_HAS_GNU_REPO */ diff --git a/docs/tutorials/007/007.dsp b/docs/tutorials/007/007.dsp deleted file mode 100644 index d069843ec50..00000000000 --- a/docs/tutorials/007/007.dsp +++ /dev/null @@ -1,124 +0,0 @@ -# Microsoft Developer Studio Project File - Name="007" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=007 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "007.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "007.mak" CFG="007 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "007 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "007 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "007 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "007 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "007 - Win32 Release"
-# Name "007 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\client_acceptor.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\client_handler.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\thread_pool.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\client_acceptor.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\client_handler.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\thread_pool.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/007/Makefile b/docs/tutorials/007/Makefile deleted file mode 100644 index 8e430900570..00000000000 --- a/docs/tutorials/007/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -# You can generally find a Makefile in the ACE examples, tests or the library -# itself that will satisfy our application needs. This one was taken from -# one of the examples. - - # Define the name of the binary we want to create. There has to be - # a CPP file $(BIN).cpp but it doesn't necessarily have to have your - # main() in it. Most of the time, though, it will. -BIN = server - - # Few applications will have a single source file. We use the FILES - # macro to build up a list of additional files to compile. Notice - # that we leave off the extension just as with BIN -FILES = -FILES += client_handler -FILES += client_acceptor -FILES += thread_pool - - # The BUILD macro is used by the ACE makefiles. Basically, it tells - # the system what to build. I don't really know what VBIN is other - # than it is constructed from the value of BIN. Just go with it... -BUILD = $(VBIN) - - # Here we use some GNU make extensions to build the SRC macro. Basically, - # we're just adding .cpp to the value of BIN and for each entry of the - # FILES macro. -SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix .cpp,$(FILES)) - - # This is used by my Indent target below. It's not a part of standard - # ACE and you don't need it yourself. -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - - # This is where the real power lies! These included makefile components - # are similar to the C++ templates in ACE. That is, they do a tremendous - # amount of work for you and all you have to do is include them. - # As a matter of fact, in our project, I created a single file named - # "app.mk" that includes all of these. Our project makefiles then just - # need to include app.mk to get everything they need. - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - - # Sometimes I like to reformat my code to make it more readable. This is - # more useful for the comments than anything else. Unfortunately, the - # "indent" program doesn't quite grok C++ so I have to post-process it's - # output just a bit. -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - - # One of the targets in the ACE makefiles is "depend". It will invoke - # your compiler in a way that will generate a list of dependencies for - # you. This is a great thing! Unfortunately, it puts all of that mess - # directly into the Makefile. I prefer my Makefile to stay clean and - # uncluttered. The perl script referenced here pulls the dependency - # stuff back out of the Makefile and into a file ".depend" which we then - # include just like the makefile components above. -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! - - # This is inserted by the fix.Makefile script -include .depend diff --git a/docs/tutorials/007/client_acceptor.cpp b/docs/tutorials/007/client_acceptor.cpp deleted file mode 100644 index 6cc90612558..00000000000 --- a/docs/tutorials/007/client_acceptor.cpp +++ /dev/null @@ -1,67 +0,0 @@ - -// $Id$ - -#include "client_acceptor.h" - -/* - Construct ourselves with the chosen concurrency strategy. Notice that we also - set our Thread_Pool reference to our private instance. - */ -Client_Acceptor::Client_Acceptor( int _concurrency ) - : concurrency_(_concurrency) - ,the_thread_pool_(private_thread_pool_) -{ -} - -/* - Construct ourselves with a reference to somebody else' Thread_Pool. Obvioulsy - our concurrency strategy is "thread_pool_" at this point. - */ -Client_Acceptor::Client_Acceptor( Thread_Pool & _thread_pool ) - : concurrency_(thread_pool_) - ,the_thread_pool_(_thread_pool) -{ -} - -/* - When we're destructed, we may need to cleanup after ourselves. If we're running - with a thread pool that we own, it is up to us to close it down. - */ -Client_Acceptor::~Client_Acceptor( void ) -{ - if( this->concurrency() == thread_pool_ && thread_pool_is_private() ) - { - thread_pool()->close(); - } -} - -/* - Similar to the destructor (and close() below) it is necessary for us to open the - thread pool in some circumstances. - - Notice how we delegate most of the open() work to the open() method of our baseclass. - */ -int Client_Acceptor::open( const ACE_INET_Addr & _addr, ACE_Reactor * _reactor, int _pool_size ) -{ - if( this->concurrency() == thread_pool_ && thread_pool_is_private() ) - { - thread_pool()->open(_pool_size); - } - - return inherited::open(_addr,_reactor); -} - -/* - Here again we find that we have to manage the thread pool. Like open() we also delegate - the other work to our baseclass. - */ -int Client_Acceptor::close(void) -{ - if( this->concurrency() == thread_pool_ && thread_pool_is_private() ) - { - thread_pool()->close(); - } - - return inherited::close(); -} - diff --git a/docs/tutorials/007/client_acceptor.h b/docs/tutorials/007/client_acceptor.h deleted file mode 100644 index 82c761879ea..00000000000 --- a/docs/tutorials/007/client_acceptor.h +++ /dev/null @@ -1,141 +0,0 @@ - -// $Id$ - -#ifndef CLIENT_ACCEPTOR_H -#define CLIENT_ACCEPTOR_H - -/* - The ACE_Acceptor<> template lives in the ace/Acceptor.h header file. You'll - find a very consitent naming convention between the ACE objects and the - headers where they can be found. In general, the ACE object ACE_Foobar will - be found in ace/Foobar.h. - */ - -#include "ace/Acceptor.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - Since we want to work with sockets, we'll need a SOCK_Acceptor to allow the - clients to connect to us. - */ -#include "ace/SOCK_Acceptor.h" - -/* - The Client_Handler object we develop will be used to handle clients once - they're connected. The ACE_Acceptor<> template's first parameter requires - such an object. In some cases, you can get by with just a forward - declaration on the class, in others you have to have the whole thing. - */ -#include "client_handler.h" - -/* - Parameterize the ACE_Acceptor<> such that it will listen for socket - connection attempts and create Client_Handler objects when they happen. In - Tutorial 001, we wrote the basic acceptor logic on our own before we - realized that ACE_Acceptor<> was available. You'll get spoiled using the - ACE templates because they take away a lot of the tedious details! - */ -typedef ACE_Acceptor < Client_Handler, ACE_SOCK_ACCEPTOR > Client_Acceptor_Base; - -#include "thread_pool.h" - -/* - This time we've added quite a bit more to our acceptor. In addition to - providing a choice of concurrency strategies, we also maintain a Thread_Pool - object in case that strategy is chosen. The object still isn't very complex - but it's come a long way from the simple typedef we had in Tutorial 5. - - Why keep the thread pool as a member? If we go back to the inetd concept - you'll recall that we need several acceptors to make that work. We may have - a situation in which our different client types requre different resources. - That is, we may need a large thread pool for some client types and a smaller - one for others. We could share a pool but then the client types may have - undesirable impact on one another. - - Just in case you do want to share a single thread pool, there is a constructor - below that will let you do that. - */ -class Client_Acceptor : public Client_Acceptor_Base -{ -public: - typedef Client_Acceptor_Base inherited; - - /* - Now that we have more than two strategies, we need more than a boolean - to tell us what we're using. A set of enums is a good choice because - it allows us to use named values. Another option would be a set of - static const integers. - */ - enum concurrency_t - { - single_threaded_, - thread_per_connection_, - thread_pool_ - }; - - /* - The default constructor allows the programmer to choose the concurrency - strategy. Since we want to focus on thread-pool, that's what we'll use - if nothing is specified. - */ - Client_Acceptor( int _concurrency = thread_pool_ ); - - /* - Another option is to construct the object with an existing thread pool. - The concurrency strategy is pretty obvious at that point. - */ - Client_Acceptor( Thread_Pool & _thread_pool ); - - /* - Our destructor will take care of shutting down the thread-pool - if applicable. - */ - ~Client_Acceptor( void ); - - /* - Open ourselves and register with the given reactor. The thread pool size - can be specified here if you want to use that concurrency strategy. - */ - int open( const ACE_INET_Addr & _addr, ACE_Reactor * _reactor, - int _pool_size = Thread_Pool::default_pool_size_ ); - - /* - Close ourselves and our thread pool if applicable - */ - int close(void); - - /* - What is our concurrency strategy? - */ - int concurrency(void) - { return this->concurrency_; } - - /* - Give back a pointer to our thread pool. Our Client_Handler objects - will need this so that their handle_input() methods can put themselves - into the pool. Another alternative would be a globally accessible - thread pool. ACE_Singleton<> is a way to achieve that. - */ - Thread_Pool * thread_pool(void) - { return & this->the_thread_pool_; } - - /* - Since we can be constructed with a Thread_Pool reference, there are times - when we need to know if the thread pool we're using is ours or if we're - just borrowing it from somebody else. - */ - int thread_pool_is_private(void) - { return &the_thread_pool_ == &private_thread_pool_; } - -protected: - int concurrency_; - - Thread_Pool private_thread_pool_; - - Thread_Pool & the_thread_pool_; -}; - -#endif // CLIENT_ACCEPTOR_H diff --git a/docs/tutorials/007/client_handler.cpp b/docs/tutorials/007/client_handler.cpp deleted file mode 100644 index 647739e34e2..00000000000 --- a/docs/tutorials/007/client_handler.cpp +++ /dev/null @@ -1,239 +0,0 @@ - -// $Id$ - -/* - Since this is the third time we've seen most of this, I'm going to strip out almost - all of the comments that you've already seen. That way, you can concentrate on the - new items. - */ - -#include "client_acceptor.h" -#include "client_handler.h" - -/* - We're going to be registering and unregistering a couple of times. To make sure that - we use the same flags every time, I've created these handy macros. - */ -#define REGISTER_MASK ACE_Event_Handler::READ_MASK -#define REMOVE_MASK (ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL) - -/* - Our constructor still doesn't really do anything. We simply initialize the acceptor - pointer to "null" and get our current thread id. The static self() method of ACE_Thread - will return you a thread id native to your platform. - */ -Client_Handler::Client_Handler (void) - : client_acceptor_(0) - ,creator_(ACE_Thread::self()) -{ -} - -Client_Handler::~Client_Handler (void) -{ - this->peer().close(); -} - -/* - Query our acceptor for the concurrency strategy. Notice that we don't bother - to check that our acceptor pointer is valid. That is proably a bad idea... - */ -int Client_Handler::concurrency(void) -{ - return this->client_acceptor()->concurrency(); -} - -/* - And here we ask the acceptor about the thread pool. - */ -Thread_Pool * Client_Handler::thread_pool(void) -{ - return this->client_acceptor()->thread_pool(); -} - -/* - Back to our open() method. This is straight out of Tutorial 6. There's - nothing additional here for the thread-pool implementation. - */ -int Client_Handler::open (void *_acceptor) -{ - client_acceptor( (Client_Acceptor *) _acceptor ); - - if( concurrency() == Client_Acceptor::thread_per_connection_ ) - { - return this->activate(); - } - - this->reactor (client_acceptor()->reactor ()); - - ACE_INET_Addr addr; - - if (this->peer ().get_remote_addr (addr) == -1) - { - return -1; - } - - if (this->reactor ()->register_handler (this, REGISTER_MASK) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - } - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ())); - - return 0; -} - -/* - The destroy() method will remove us from the reactor (with the - DONT_CALL flag set!) and then free our memory. This allows us to - be closed from outside of the reactor context without any danger. - */ -void Client_Handler::destroy (void) -{ - this->reactor ()->remove_handler (this, REMOVE_MASK ); - delete this; -} - -/* - As mentioned in the header, the typical way to close an object in a - threaded context is to invoke it's close() method. -*/ -int Client_Handler::close(u_long flags) -{ - /* - We use the destroy() method to clean up after ourselves. - That will take care of removing us from the reactor and then - freeing our memory. - */ - this->destroy(); - - /* - Don't forward the close() to the baseclass! handle_close() above has - already taken care of delete'ing. Forwarding close() would cause that - to happen again and things would get really ugly at that point! - */ - return 0; -} - -/* - We will be called when handle_input() returns -1. That's our queue - to delete ourselves to prevent memory leaks. - */ -int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask) -{ - ACE_UNUSED_ARG (_handle); - ACE_UNUSED_ARG (_mask); - - delete this; - - return 0; -} - -/* - In the open() method, we registered with the reactor and requested to be - notified when there is data to be read. When the reactor sees that activity - it will invoke this handle_input() method on us. As I mentioned, the _handle - parameter isn't useful to us but it narrows the list of methods the reactor - has to worry about and the list of possible virtual functions we would have - to override. - - You've read that much before... Now we have to do some extra stuff in case - we're using the thread-pool implementation. If we're called by our creator - thread then we must be in the reactor. In that case, we arrange to be put - into the thread pool. If we're not in the creator thread then we must be - in the thread pool and we can do some work. - */ -int Client_Handler::handle_input (ACE_HANDLE _handle) -{ - ACE_UNUSED_ARG (_handle); - - /* - Check our strategy. If we're using the thread pool and we're in the creation - thread then we know we were called by the reactor. - */ - if( concurrency() == Client_Acceptor::thread_pool_ ) - { - if( ACE_OS::thr_equal(ACE_Thread::self(),creator_) ) - { - /* - Remove ourselves from the reactor and ask to be put into the thread pool's - queue of work. (You should be able to use suspend_handler() but I've had - problems with that.) - */ - this->reactor()->remove_handler( this, REMOVE_MASK ); - return this->thread_pool()->enqueue(this); - } - } - - /* - Any strategy other than thread-per-connection will eventually get here. If we're in the - single-threaded implementation or the thread-pool, we still have to pass this way. - */ - - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the process() method to do the work but save it's return value instead - of returning it immediately. - */ - - int rval = this->process(buf,sizeof(buf)); - - /* - Now, we look again to see if we're in the thread-pool implementation. If so then we - need to re-register ourselves with the reactor so that we can get more work when it - is available. (If suspend_handler() worked then we would use resume_handler() here.) - */ - if( concurrency() == Client_Acceptor::thread_pool_ ) - { - if( rval != -1 ) - { - this->reactor()->register_handler( this, REGISTER_MASK ); - } - } - - /* - Return the result of process() - */ - return(rval); -} - -/* - Remember that when we leave our svc() method, the framework will take care - of calling our close() method so that we can cleanup after ourselves. - */ -int Client_Handler::svc(void) -{ - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - while( 1 ) - { - if( this->process(buf,sizeof(buf)) == -1 ) - { - return(-1); - } - } - - return(0); -} - -/* - Once again, we see that the application-level logic has not been at all affected - by our choice of threading models. Of course, I'm not sharing data between threads - or anything. We'll leave locking issues for a later tutorial. - */ -int Client_Handler::process (char *_rdbuf, int _rdbuf_len) -{ - switch (this->peer ().recv (_rdbuf, _rdbuf_len)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf)); - } - - return 0; -} diff --git a/docs/tutorials/007/client_handler.h b/docs/tutorials/007/client_handler.h deleted file mode 100644 index 6807231c3b0..00000000000 --- a/docs/tutorials/007/client_handler.h +++ /dev/null @@ -1,172 +0,0 @@ - -// $Id$ - -#ifndef CLIENT_HANDLER_H -#define CLIENT_HANDLER_H - -/* - Our client handler must exist somewhere in the ACE_Event_Handler object - hierarchy. This is a requirement of the ACE_Reactor because it maintains - ACE_Event_Handler pointers for each registered event handler. You could - derive our Client_Handler directly from ACE_Event_Handler but you still have - to have an ACE_SOCK_Stream for the actually connection. With a direct - derivative of ACE_Event_Handler, you'll have to contain and maintain an - ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a - derivative of ACE_Event_Handler) some of those details are handled for you. - */ - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" - -class Client_Acceptor; -class Thread_Pool; - -/* - Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<> - interface as well. That's what the ACE_NULL_SYNCH parameter below is all - about. That's beyond our scope here but we'll come back to it in the next - tutorial when we start looking at concurrency options. - */ -class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - typedef ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited; - - // Constructor... - Client_Handler (void); - - /* - The destroy() method is our preferred method of destruction. We could - have overloaded the delete operator but that is neither easy nor - intuitive (at least to me). Instead, we provide a new method of - destruction and we make our destructor protected so that only ourselves, - our derivatives and our friends can delete us. It's a nice - compromise. - */ - void destroy (void); - - /* - Most ACE objects have an open() method. That's how you make them ready - to do work. ACE_Event_Handler has a virtual open() method which allows us - to create this overrride. ACE_Acceptor<> will invoke this method after - creating a new Client_Handler when a client connects. Notice that the - parameter to open() is a void*. It just so happens that the pointer - points to the acceptor which created us. You would like for the parameter - to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that - would tie it too closely to the ACE_Acceptor<> set of objects. In our - definition of open() you'll see how we get around that. - */ - int open (void *_acceptor); - - /* - When an ACE_Task<> object falls out of the svc() method, the framework - will call the close() method. That's where we want to cleanup ourselves - if we're running in either thread-per-connection or thread-pool mode. - */ - int close(u_long flags = 0); - - /* - When there is activity on a registered handler, the handle_input() method - of the handler will be invoked. If that method returns an error code (eg - -- -1) then the reactor will invoke handle_close() to allow the object to - clean itself up. Since an event handler can be registered for more than - one type of callback, the callback mask is provided to inform - handle_close() exactly which method failed. That way, you don't have to - maintain state information between your handle_* method calls. The _handle - parameter is explained below... - As a side-effect, the reactor will also invoke remove_handler() - for the object on the mask that caused the -1 return. This means - that we don't have to do that ourselves! - */ - int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask); - - /* - When we register with the reactor, we're going to tell it that we want to - be notified of READ events. When the reactor sees that there is read - activity for us, our handle_input() will be invoked. The _handleg - provided is the handle (file descriptor in Unix) of the actual connection - causing the activity. Since we're derived from ACE_Svc_Handler<> and it - maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for - us. However, if we had been derived directly from ACE_Event_Handler, we - may have chosen not to contain the peer. In that case, the _handleg - would be important to us for reading the client's data. - */ - int handle_input (ACE_HANDLE _handle); - -protected: - - /* - If the Client_Acceptor which created us has chosen a thread-per-connection - strategy then our open() method will activate us into a dedicate thread. - The svc() method will then execute in that thread performing some of the - functions we used to leave up to the reactor. - */ - int svc(void); - - /* - This has nothing at all to do with ACE. I've added this here as a worker - function which I will call from handle_input(). That allows me to - introduce concurrencly in later tutorials with a no changes to the worker - function. You can think of process() as application-level code and - everything elase as application-framework code. - */ - int process (char *_rdbuf, int _rdbuf_len); - - /* - We don't really do anything in our destructor but we've declared it to be - protected to prevent casual deletion of this object. As I said above, I - really would prefer that everyone goes through the destroy() method to get - rid of us. - */ - ~Client_Handler (void); - - /* - When we get to the definition of Client_Handler we'll see that there are - several places where we go back to the Client_Acceptor for information. - It is generally a good idea to do that through an accesor rather than - using the member variable directly. - */ - Client_Acceptor * client_acceptor( void ) - { return this->client_acceptor_; } - - /* - And since you shouldn't access a member variable directly, neither should you - set (mutate) it. Although it might seem silly to do it this way, you'll thank - yourself for it later. - */ - void client_acceptor( Client_Acceptor * _client_acceptor ) - { this->client_acceptor_ = _client_acceptor; } - - /* - The concurrency() accessor tells us the current concurrency strategy. It actually - queries the Client_Acceptor for it but by having the accessor in place, we could - change our implementation without affecting everything that needs to know. - */ - int concurrency(void); - - /* - Likewise for access to the Thread_Pool that we belong to. - */ - Thread_Pool * thread_pool(void); - - - Client_Acceptor * client_acceptor_; - - /* - For some reason I didn't create accessor/mutator methods for this. So much for - consistency.... - - This variable is used to remember the thread in which we were created: the "creator" - thread in other words. handle_input() needs to know if it is operating in the - main reactor thread (which is the one that created us) or if it is operating in - one of the thread pool threads. More on this when we get to handle_input(). - */ - ACE_thread_t creator_; -}; - -#endif // CLIENT_HANDLER_H diff --git a/docs/tutorials/007/fix.Makefile b/docs/tutorials/007/fix.Makefile deleted file mode 100755 index e99c194114a..00000000000 --- a/docs/tutorials/007/fix.Makefile +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/perl - - # Open the Makefile that has been mangled by 'make depend' - # and suck it into a perl array. -open(IF,"<Makefile") || die; -@makefile = <IF>; -close(IF); - - # Now open our .depend file and a temporary Makefile. - # We'll split the original Makefile between these two. -open(DF,">.depend") || die; -open(MF,">Makefile.tmp") || die; - - # For each line we read out of the original file... -foreach (@makefile) { - - # If we're into the dependency section, write the line - # into the .depend file. - # - if( $depend ) { - print DF $_; - } - else { - # If we haven't gotten to the dependency section yet - # then see if the current line is the separator that - # "make depend" causes to be inserted. - # - if( m/^\Q# DO NOT DELETE THIS LINE -- g++dep uses it.\E/ ) { - - # If so, change our "mode" and skip this line. - ++$depend; - next; - } - - # Also skip the "include .depend" that we insert. If we - # don't do this, it is possible to have a bunch of these - # inserted into the output when we read an unmangled Makefile - next if( m/^include .depend/ ); - - # Print the non-dependency info to the temporary Makefile - print MF $_; - } -} - -# Tell our new Makefile to include the dependency file -print MF "include .depend\n"; - -# Close the two output files... -close(DF); -close(MF); - -# Unlink (remove) the original Makefile and rename our -# temporary file. There's obviously room for error checking -# here but we've got the Makefile checked into some revision -# control system anyway. Don't we? - -unlink("Makefile"); -rename("Makefile.tmp","Makefile"); - -exit(0); diff --git a/docs/tutorials/007/page01.html b/docs/tutorials/007/page01.html deleted file mode 100644 index 24b94f686c7..00000000000 --- a/docs/tutorials/007/page01.html +++ /dev/null @@ -1,33 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In this tutorial, we're going to extend Tutorial 6 to add a third concurrency -strategy: thread-pool. Like Tutorial 6 did to Tutorial 5, we're -going to keep the existing strategies that we've already created and add -this one in as a "bonus". As you'll see, our basic objects will change -but not by a whole lot. To accomplish this, we'll introduce one new -major object that helps to abstract the thread pool concept. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page02.html b/docs/tutorials/007/page02.html deleted file mode 100644 index c6e7bedec43..00000000000 --- a/docs/tutorials/007/page02.html +++ /dev/null @@ -1,197 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>As usualy, we start with <A HREF="server.cpp">server.cpp</A> -<BR> -<HR WIDTH="100%"> - -<P><FONT FACE="Arial,Helvetica">// $Id: server.cpp,v 1.1 1998/08/30 16:04:12 -jcej Exp $</FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> We try to keep main() very -simple. One of the ways we do that is to push</FONT> -<BR><FONT FACE="Arial,Helvetica"> much of the complicated stuff -into worker objects. In this case, we only</FONT> -<BR><FONT FACE="Arial,Helvetica"> need to include the acceptor -header in our main source file. We let it</FONT> -<BR><FONT FACE="Arial,Helvetica"> worry about the "real work".</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> - -<P><FONT FACE="Arial,Helvetica">#include "client_acceptor.h"</FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> As before, we create a simple -signal handler that will set our finished</FONT> -<BR><FONT FACE="Arial,Helvetica"> flag. There are, of -course, more elegant ways to handle program shutdown</FONT> -<BR><FONT FACE="Arial,Helvetica"> requests but that isn't really -our focus right now, so we'll just do the</FONT> -<BR><FONT FACE="Arial,Helvetica"> easiest thing.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> - -<P><FONT FACE="Arial,Helvetica">static sig_atomic_t finished = 0;</FONT> -<BR><FONT FACE="Arial,Helvetica">extern "C" void handler (int)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> finished = 1;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> A server has to listen for -clients at a known TCP/IP port. The default ACE</FONT> -<BR><FONT FACE="Arial,Helvetica"> port is 10002 (at least on -my system) and that's good enough for what we</FONT> -<BR><FONT FACE="Arial,Helvetica"> want to do here. Obviously, -a more robust application would take a command</FONT> -<BR><FONT FACE="Arial,Helvetica"> line parameter or read from -a configuration file or do some other clever</FONT> -<BR><FONT FACE="Arial,Helvetica"> thing. Just like the -signal handler above, though, that's what we want to</FONT> -<BR><FONT FACE="Arial,Helvetica"> focus on, so we're taking -the easy way out.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> - -<P><FONT FACE="Arial,Helvetica">static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Finally, we get to main. -Some C++ compilers will complain loudly if your</FONT> -<BR><FONT FACE="Arial,Helvetica"> function signature doesn't -match the prototype. Even though we're not</FONT> -<BR><FONT FACE="Arial,Helvetica"> going to use the parameters, -we still have to specify them.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> - -<P><FONT FACE="Arial,Helvetica">int main (int argc, char *argv[])</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> In our earlier servers, we -used a global pointer to get to the reactor. I've</FONT> -<BR><FONT FACE="Arial,Helvetica"> never really liked that idea, -so I've moved it into main() this time. When</FONT> -<BR><FONT FACE="Arial,Helvetica"> we get to the Client_Handler -object you'll see how we manage to get a</FONT> -<BR><FONT FACE="Arial,Helvetica"> pointer back to this reactor.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_Reactor reactor;</FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The acceptor -will take care of letting clients connect to us. It will</FONT> -<BR><FONT FACE="Arial,Helvetica"> also arrange -for a Client_Handler to be created for each new client.</FONT> -<BR><FONT FACE="Arial,Helvetica"> Since we're only -going to listen at one TCP/IP port, we only need one</FONT> -<BR><FONT FACE="Arial,Helvetica"> acceptor. -If we wanted, though, we could create several of these and</FONT> -<BR><FONT FACE="Arial,Helvetica"> listen at several -ports. (That's what we would do if we wanted to rewrite</FONT> -<BR><FONT FACE="Arial,Helvetica"> inetd for -instance.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> Client_Acceptor peer_acceptor;</FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Create an ACE_INET_Addr -that represents our endpoint of a connection. We</FONT> -<BR><FONT FACE="Arial,Helvetica"> then open our -acceptor object with that Addr. Doing so tells the acceptor</FONT> -<BR><FONT FACE="Arial,Helvetica"> where to listen -for connections. Servers generally listen at "well known"</FONT> -<BR><FONT FACE="Arial,Helvetica"> addresses. -If not, there must be some mechanism by which the client is</FONT> -<BR><FONT FACE="Arial,Helvetica"> informed of the -server's address.</FONT> - -<P><FONT FACE="Arial,Helvetica"> Note how ACE_ERROR_RETURN -is used if we fail to open the acceptor. This</FONT> -<BR><FONT FACE="Arial,Helvetica"> technique is -used over and over again in our tutorials.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> if (peer_acceptor.open (ACE_INET_Addr -(PORT), &reactor) == -1)</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_ERROR_RETURN ((LM_ERROR, -"%p\n", "open"), -1);</FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Install our signal -handler. You can actually register signal handlers</FONT> -<BR><FONT FACE="Arial,Helvetica"> with the reactor. -You might do that when the signal handler is</FONT> -<BR><FONT FACE="Arial,Helvetica"> responsible for -performing "real" work. Our simple flag-setter doesn't</FONT> -<BR><FONT FACE="Arial,Helvetica"> justify deriving -from ACE_Event_Handler and providing a callback function</FONT> -<BR><FONT FACE="Arial,Helvetica"> though.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_Sig_Action sa ((ACE_SignalHandler) -handler, SIGINT);</FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Like ACE_ERROR_RETURN, -the ACE_DEBUG macro gets used quite a bit. It's a</FONT> -<BR><FONT FACE="Arial,Helvetica"> handy way to -generate uniform debug output from your program.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_DEBUG ((LM_DEBUG, "(%P|%t) -starting up server daemon\n"));</FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> This will loop -"forever" invoking the handle_events() method of our</FONT> -<BR><FONT FACE="Arial,Helvetica"> reactor. handle_events() -watches for activity on any registered handlers</FONT> -<BR><FONT FACE="Arial,Helvetica"> and invokes their -appropriate callbacks when necessary. Callback-driven</FONT> -<BR><FONT FACE="Arial,Helvetica"> programming is -a big thing in ACE, you should get used to it. If the</FONT> -<BR><FONT FACE="Arial,Helvetica"> signal handler -catches something, the finished flag will be set and we'll</FONT> -<BR><FONT FACE="Arial,Helvetica"> exit. Conveniently -enough, handle_events() is also interrupted by signals</FONT> -<BR><FONT FACE="Arial,Helvetica"> and will exit -back to the while() loop. (If you want your event loop to</FONT> -<BR><FONT FACE="Arial,Helvetica"> not be interrupted -by signals, checkout the <i>restart</i> flag on the</FONT> -<BR><FONT FACE="Arial,Helvetica"> open() method -of ACE_Reactor if you're interested.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> while (!finished)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -reactor.handle_events ();</FONT> - -<P><FONT FACE="Arial,Helvetica"> ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting -down server daemon\n"));</FONT> -<BR><FONT FACE="Arial,Helvetica"> </FONT> -<BR><FONT FACE="Arial,Helvetica"> return 0;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT> - -<P> -<HR WIDTH="100%"> - -<P>Hmmm... No change there. Maybe I should leave out comments -on the stuff I don't change. Let's take a lookt at client_acceptor.h. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page03.html b/docs/tutorials/007/page03.html deleted file mode 100644 index af048108811..00000000000 --- a/docs/tutorials/007/page03.html +++ /dev/null @@ -1,263 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Let's see what things we've had to add to <A HREF="client_acceptor.h">client_acceptor.h</A>. - -<P> -<HR WIDTH="100%"> -<BR><FONT FACE="Arial,Helvetica">// $Id: client_acceptor.h,v 1.1 1998/08/30 -16:04:11 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#ifndef CLIENT_ACCEPTOR_H</FONT> -<BR><FONT FACE="Arial,Helvetica">#define CLIENT_ACCEPTOR_H</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The ACE_Acceptor<> template -lives in the ace/Acceptor.h header file. You'll</FONT> -<BR><FONT FACE="Arial,Helvetica"> find a very consitent naming -convention between the ACE objects and the</FONT> -<BR><FONT FACE="Arial,Helvetica"> headers where they can be -found. In general, the ACE object ACE_Foobar will</FONT> -<BR><FONT FACE="Arial,Helvetica"> be found in ace/Foobar.h.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "ace/Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Since we want to work with -sockets, we'll need a SOCK_Acceptor to allow the</FONT> -<BR><FONT FACE="Arial,Helvetica"> clients to connect to us.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "ace/SOCK_Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The Client_Handler object -we develop will be used to handle clients once</FONT> -<BR><FONT FACE="Arial,Helvetica"> they're connected. -The ACE_Acceptor<> template's first parameter requires</FONT> -<BR><FONT FACE="Arial,Helvetica"> such an object. In -some cases, you can get by with just a forward</FONT> -<BR><FONT FACE="Arial,Helvetica"> declaration on the class, -in others you have to have the whole thing.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "client_handler.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Parameterize the ACE_Acceptor<> -such that it will listen for socket</FONT> -<BR><FONT FACE="Arial,Helvetica"> connection attempts and create -Client_Handler objects when they happen. In</FONT> -<BR><FONT FACE="Arial,Helvetica"> Tutorial 001, we wrote the -basic acceptor logic on our own before we</FONT> -<BR><FONT FACE="Arial,Helvetica"> realized that ACE_Acceptor<> -was available. You'll get spoiled using the</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE templates because they -take away a lot of the tedious details!</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">typedef ACE_Acceptor < Client_Handler, -ACE_SOCK_ACCEPTOR > Client_Acceptor_Base;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "thread_pool.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> This time we've added quite -a bit more to our acceptor. In addition to</FONT> -<BR><FONT FACE="Arial,Helvetica"> providing a choice of concurrency -strategies, we also maintain a Thread_Pool</FONT> -<BR><FONT FACE="Arial,Helvetica"> object in case that strategy -is chosen. The object still isn't very complex</FONT> -<BR><FONT FACE="Arial,Helvetica"> but it's come a long way -from the simple typedef we had in Tutorial 5.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> Why keep the thread pool as -a member? If we go back to the inetd concept</FONT> -<BR><FONT FACE="Arial,Helvetica"> you'll recall that we need -several acceptors to make that work. We may have</FONT> -<BR><FONT FACE="Arial,Helvetica"> a situation in which our -different client types requre different resources.</FONT> -<BR><FONT FACE="Arial,Helvetica"> That is, we may need a large -thread pool for some client types and a smaller</FONT> -<BR><FONT FACE="Arial,Helvetica"> one for others. We -could share a pool but then the client types may have</FONT> -<BR><FONT FACE="Arial,Helvetica"> undesirable impact on one -another.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> Just in case you do want to -share a single thread pool, there is a constructor</FONT> -<BR><FONT FACE="Arial,Helvetica"> below that will let you do -that.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">class Client_Acceptor : public Client_Acceptor_Base</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">public:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -typedef Client_Acceptor_Base inherited;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Now that we have more than two strategies, we need more than a boolean</FONT> -<BR><FONT FACE="Arial,Helvetica"> -to tell us what we're using. A set of enums is a good choice because</FONT> -<BR><FONT FACE="Arial,Helvetica"> -it allows us to use named values. Another option would be a set of</FONT> -<BR><FONT FACE="Arial,Helvetica"> -static const integers.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -enum concurrency_t</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -single_threaded_,</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread_per_connection_,</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread_pool_</FONT> -<BR><FONT FACE="Arial,Helvetica"> -};</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -The default constructor allows the programmer to choose the concurrency</FONT> -<BR><FONT FACE="Arial,Helvetica"> -strategy. Since we want to focus on thread-pool, that's what we'll -use</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if nothing is specified.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Client_Acceptor( int _concurrency = thread_pool_ );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Another option is to construct the object with an existing thread pool.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -The concurrency strategy is pretty obvious at that point.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Client_Acceptor( Thread_Pool & _thread_pool );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Our destructor will take care of shutting down the thread-pool</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if applicable.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -~Client_Acceptor( void );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Open ourselves and register with the given reactor. The thread pool -size</FONT> -<BR><FONT FACE="Arial,Helvetica"> -can be specified here if you want to use that concurrency strategy.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int open( const ACE_INET_Addr & _addr, ACE_Reactor * _reactor,</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int _pool_size = Thread_Pool::default_pool_size_ );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Close ourselves and our thread pool if applicable</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int close(void);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -What is our concurrency strategy?</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int concurrency(void)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{ return this->concurrency_; }</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Give back a pointer to our thread pool. Our Client_Handler objects</FONT> -<BR><FONT FACE="Arial,Helvetica"> -will need this so that their handle_input() methods can put themselves</FONT> -<BR><FONT FACE="Arial,Helvetica"> -into the pool. Another alternative would be a globally accessible</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread pool. ACE_Singleton<> is a way to achieve that.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Thread_Pool * thread_pool(void)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{ return & this->the_thread_pool_; }</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Since we can be constructed with a Thread_Pool reference, there are times</FONT> -<BR><FONT FACE="Arial,Helvetica"> -when we need to know if the thread pool we're using is ours or if we're</FONT> -<BR><FONT FACE="Arial,Helvetica"> -just borrowing it from somebody else.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int thread_pool_is_private(void)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{ return &the_thread_pool_ == &private_thread_pool_; }</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">protected:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int concurrency_;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -Thread_Pool private_thread_pool_;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -Thread_Pool & the_thread_pool_;</FONT> -<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#endif // CLIENT_ACCEPTOR_H</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P> -<HR WIDTH="100%"> - -<P>Well, except for the new Thread_Pool member variable, most of the changes -are informational. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page04.html b/docs/tutorials/007/page04.html deleted file mode 100644 index 34424605180..00000000000 --- a/docs/tutorials/007/page04.html +++ /dev/null @@ -1,133 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Something new this time is <A HREF="client_acceptor.cpp">client_acceptor.cpp</A>. -I finally had enough code to move it out of the header. - -<P> -<HR WIDTH="100%"> -<BR><FONT FACE="Arial,Helvetica">// $Id: client_acceptor.cpp,v 1.1 1998/08/30 -16:04:11 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "client_acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Construct ourselves with -the chosen concurrency strategy. Notice that we also</FONT> -<BR><FONT FACE="Arial,Helvetica"> set our Thread_Pool reference -to our private instance.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">Client_Acceptor::Client_Acceptor( int -_concurrency )</FONT> -<BR><FONT FACE="Arial,Helvetica"> : concurrency_(_concurrency)</FONT> -<BR><FONT FACE="Arial,Helvetica"> ,the_thread_pool_(private_thread_pool_)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Construct ourselves with -a reference to somebody else' Thread_Pool. Obvioulsy</FONT> -<BR><FONT FACE="Arial,Helvetica"> our concurrency strategy -is "thread_pool_" at this point.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">Client_Acceptor::Client_Acceptor( Thread_Pool -& _thread_pool )</FONT> -<BR><FONT FACE="Arial,Helvetica"> : concurrency_(thread_pool_)</FONT> -<BR><FONT FACE="Arial,Helvetica"> ,the_thread_pool_(_thread_pool)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> When we're destructed, we -may need to cleanup after ourselves. If we're running</FONT> -<BR><FONT FACE="Arial,Helvetica"> with a thread pool that we -own, it is up to us to close it down.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">Client_Acceptor::~Client_Acceptor( void -)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( this->concurrency() == thread_pool_ && thread_pool_is_private() -)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread_pool()->close();</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Similar to the destructor -(and close() below) it is necessary for us to open the</FONT> -<BR><FONT FACE="Arial,Helvetica"> thread pool in some circumstances.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> Notice how we delegate most -of the open() work to the open() method of our baseclass.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Client_Acceptor::open( const ACE_INET_Addr -& _addr, ACE_Reactor * _reactor, int _pool_size )</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( this->concurrency() == thread_pool_ && thread_pool_is_private() -)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread_pool()->open(_pool_size);</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -return inherited::open(_addr,_reactor);</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Here again we find that we -have to manage the thread pool. Like open() we also delegate</FONT> -<BR><FONT FACE="Arial,Helvetica"> the other work to our baseclass.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Client_Acceptor::close(void)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( this->concurrency() == thread_pool_ && thread_pool_is_private() -)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread_pool()->close();</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -return inherited::close();</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT> -<BR><FONT FACE="Arial,Helvetica"></FONT> <FONT FACE="Arial,Helvetica"></FONT> - -<P> -<HR WIDTH="100%"> - -<P>Nothing really surprising here. Most of it just manages the Thread_Pool. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page05.html b/docs/tutorials/007/page05.html deleted file mode 100644 index c797b188cec..00000000000 --- a/docs/tutorials/007/page05.html +++ /dev/null @@ -1,208 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>As you might expect, <A HREF="client_handler.h">client_handler.h</A> -is next. - -<P> -<HR WIDTH="100%"> -<pre><FONT FACE="Arial,Helvetica"> -#ifndef CLIENT_HANDLER_H -#define CLIENT_HANDLER_H - -/* - Our client handler must exist somewhere in the ACE_Event_Handler object - hierarchy. This is a requirement of the ACE_Reactor because it maintains - ACE_Event_Handler pointers for each registered event handler. You could - derive our Client_Handler directly from ACE_Event_Handler but you still have - to have an ACE_SOCK_Stream for the actually connection. With a direct - derivative of ACE_Event_Handler, you'll have to contain and maintain an - ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a - derivative of ACE_Event_Handler) some of those details are handled for you. - */ - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" - -class Client_Acceptor; -class Thread_Pool; - -/* - Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<> - interface as well. That's what the ACE_NULL_SYNCH parameter below is all - about. That's beyond our scope here but we'll come back to it in the next - tutorial when we start looking at concurrency options. - */ -class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - typedef ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited; - - // Constructor... - Client_Handler (void); - - /* - The destroy() method is our preferred method of destruction. We could - have overloaded the delete operator but that is neither easy nor - intuitive (at least to me). Instead, we provide a new method of - destruction and we make our destructor protected so that only ourselves, - our derivatives and our friends can delete us. It's a nice - compromise. - */ - void destroy (void); - - /* - Most ACE objects have an open() method. That's how you make them ready - to do work. ACE_Event_Handler has a virtual open() method which allows us - to create this overrride. ACE_Acceptor<> will invoke this method after - creating a new Client_Handler when a client connects. Notice that the - parameter to open() is a void*. It just so happens that the pointer - points to the acceptor which created us. You would like for the parameter - to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that - would tie it too closely to the ACE_Acceptor<> set of objects. In our - definition of open() you'll see how we get around that. - */ - int open (void *_acceptor); - - /* - When an ACE_Task<> object falls out of the svc() method, the framework - will call the close() method. That's where we want to cleanup ourselves - if we're running in either thread-per-connection or thread-pool mode. - */ - int close(u_long flags = 0); - - /* - When there is activity on a registered handler, the handle_input() method - of the handler will be invoked. If that method returns an error code (eg - -- -1) then the reactor will invoke handle_close() to allow the object to - clean itself up. Since an event handler can be registered for more than - one type of callback, the callback mask is provided to inform - handle_close() exactly which method failed. That way, you don't have to - maintain state information between your handle_* method calls. The _handle - parameter is explained below... - As a side-effect, the reactor will also invoke remove_handler() - for the object on the mask that caused the -1 return. This means - that we don't have to do that ourselves! - */ - int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask); - - /* - When we register with the reactor, we're going to tell it that we want to - be notified of READ events. When the reactor sees that there is read - activity for us, our handle_input() will be invoked. The _handleg - provided is the handle (file descriptor in Unix) of the actual connection - causing the activity. Since we're derived from ACE_Svc_Handler<> and it - maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for - us. However, if we had been derived directly from ACE_Event_Handler, we - may have chosen not to contain the peer. In that case, the _handleg - would be important to us for reading the client's data. - */ - int handle_input (ACE_HANDLE _handle); - -protected: - - /* - If the Client_Acceptor which created us has chosen a thread-per-connection - strategy then our open() method will activate us into a dedicate thread. - The svc() method will then execute in that thread performing some of the - functions we used to leave up to the reactor. - */ - int svc(void); - - /* - This has nothing at all to do with ACE. I've added this here as a worker - function which I will call from handle_input(). That allows me to - introduce concurrencly in later tutorials with a no changes to the worker - function. You can think of process() as application-level code and - everything elase as application-framework code. - */ - int process (char *_rdbuf, int _rdbuf_len); - - /* - We don't really do anything in our destructor but we've declared it to be - protected to prevent casual deletion of this object. As I said above, I - really would prefer that everyone goes through the destroy() method to get - rid of us. - */ - ~Client_Handler (void); - - /* - When we get to the definition of Client_Handler we'll see that there are - several places where we go back to the Client_Acceptor for information. - It is generally a good idea to do that through an accesor rather than - using the member variable directly. - */ - Client_Acceptor * client_acceptor( void ) - { return this->client_acceptor_; } - - /* - And since you shouldn't access a member variable directly, neither should you - set (mutate) it. Although it might seem silly to do it this way, you'll thank - yourself for it later. - */ - void client_acceptor( Client_Acceptor * _client_acceptor ) - { this->client_acceptor_ = _client_acceptor; } - - /* - The concurrency() accessor tells us the current concurrency strategy. It actually - queries the Client_Acceptor for it but by having the accessor in place, we could - change our implementation without affecting everything that needs to know. - */ - int concurrency(void); - - /* - Likewise for access to the Thread_Pool that we belong to. - */ - Thread_Pool * thread_pool(void); - - - Client_Acceptor * client_acceptor_; - - /* - For some reason I didn't create accessor/mutator methods for this. So much for - consistency.... - - This variable is used to remember the thread in which we were created: the "creator" - thread in other words. handle_input() needs to know if it is operating in the - main reactor thread (which is the one that created us) or if it is operating in - one of the thread pool threads. More on this when we get to handle_input(). - */ - ACE_thread_t creator_; -}; - -#endif // CLIENT_HANDLER_H -</pre> -<HR WIDTH="100%"> - -<P>Still, we're just not seeing a lot of changes due to intruduction of -the thread pool. That's a good thing! You don't want to go turning -your application upside down just because you changed thread models. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page06.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page06.html b/docs/tutorials/007/page06.html deleted file mode 100644 index 3c2fdd30357..00000000000 --- a/docs/tutorials/007/page06.html +++ /dev/null @@ -1,272 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P><A HREF="client_handler.cpp">client_handler.cpp</A> -shows some of the changes due to the thread-pool. Just a few -though. - -<P> -<HR WIDTH="100%"> -<pre><FONT FACE="Arial,Helvetica"> -/* - Since this is the third time we've seen most of this, I'm going to strip out almost - all of the comments that you've already seen. That way, you can concentrate on the - new items. - */ - -#include "client_acceptor.h" -#include "client_handler.h" - -/* - We're going to be registering and unregistering a couple of times. To make sure that - we use the same flags every time, I've created these handy macros. - */ -#define REGISTER_MASK ACE_Event_Handler::READ_MASK -#define REMOVE_MASK (ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL) - -/* - Our constructor still doesn't really do anything. We simply initialize the acceptor - pointer to "null" and get our current thread id. The static self() method of ACE_Thread - will return you a thread id native to your platform. - */ -Client_Handler::Client_Handler (void) - : client_acceptor_(0) - ,creator_(ACE_Thread::self()) -{ -} - -Client_Handler::~Client_Handler (void) -{ - this->peer().close(); -} - -/* - Query our acceptor for the concurrency strategy. Notice that we don't bother - to check that our acceptor pointer is valid. That is proably a bad idea... - */ -int Client_Handler::concurrency(void) -{ - return this->client_acceptor()->concurrency(); -} - -/* - And here we ask the acceptor about the thread pool. - */ -Thread_Pool * Client_Handler::thread_pool(void) -{ - return this->client_acceptor()->thread_pool(); -} - -/* - Back to our open() method. This is straight out of Tutorial 6. There's - nothing additional here for the thread-pool implementation. - */ -int Client_Handler::open (void *_acceptor) -{ - client_acceptor( (Client_Acceptor *) _acceptor ); - - if( concurrency() == Client_Acceptor::thread_per_connection_ ) - { - return this->activate(); - } - - this->reactor (client_acceptor()->reactor ()); - - ACE_INET_Addr addr; - - if (this->peer ().get_remote_addr (addr) == -1) - { - return -1; - } - - if (this->reactor ()->register_handler (this, REGISTER_MASK) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - } - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ())); - - return 0; -} - -/* - The destroy() method will remove us from the reactor (with the - DONT_CALL flag set!) and then free our memory. This allows us to - be closed from outside of the reactor context without any danger. - */ -void Client_Handler::destroy (void) -{ - this->reactor ()->remove_handler (this, REMOVE_MASK ); - delete this; -} - -/* - As mentioned in the header, the typical way to close an object in a - threaded context is to invoke it's close() method. We use the - destroy() method to clean up after ourselves. -*/ -int Client_Handler::close(u_long flags) -{ - this->destroy(); - - /* - Don't forward the close() to the baseclass! handle_close() above has - already taken care of delete'ing. Forwarding close() would cause that - to happen again and things would get really ugly at that point! - */ - return 0; -} - -/* - We will be called when handle_input() returns -1. That's our queue - to delete ourselves to prevent memory leaks. - */ -int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask) -{ - ACE_UNUSED_ARG (_handle); - ACE_UNUSED_ARG (_mask); - - delete this; - - return 0; -} - -/* - In the open() method, we registered with the reactor and requested to be - notified when there is data to be read. When the reactor sees that activity - it will invoke this handle_input() method on us. As I mentioned, the _handle - parameter isn't useful to us but it narrows the list of methods the reactor - has to worry about and the list of possible virtual functions we would have - to override. - - You've read that much before... Now we have to do some extra stuff in case - we're using the thread-pool implementation. If we're called by our creator - thread then we must be in the reactor. In that case, we arrange to be put - into the thread pool. If we're not in the creator thread then we must be - in the thread pool and we can do some work. - */ -int Client_Handler::handle_input (ACE_HANDLE _handle) -{ - ACE_UNUSED_ARG (_handle); - - /* - Check our strategy. If we're using the thread pool and we're in the creation - thread then we know we were called by the reactor. - */ - if( concurrency() == Client_Acceptor::thread_pool_ ) - { - if( ACE_OS::thr_equal(ACE_Thread::self(),creator_) ) - { - /* - Remove ourselves from the reactor and ask to be put into the thread pool's - queue of work. (You should be able to use suspend_handler() but I've had - problems with that.) - */ - this->reactor()->remove_handler( this, REMOVE_MASK ); - return this->thread_pool()->enqueue(this); - } - } - - /* - Any strategy other than thread-per-connection will eventually get here. If we're in the - single-threaded implementation or the thread-pool, we still have to pass this way. - */ - - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - /* - Invoke the process() method to do the work but save it's return value instead - of returning it immediately. - */ - - int rval = this->process(buf,sizeof(buf)); - - /* - Now, we look again to see if we're in the thread-pool implementation. If so then we - need to re-register ourselves with the reactor so that we can get more work when it - is available. (If suspend_handler() worked then we would use resume_handler() here.) - */ - if( concurrency() == Client_Acceptor::thread_pool_ ) - { - if( rval != -1 ) - { - this->reactor()->register_handler( this, REGISTER_MASK ); - } - } - - /* - Return the result of process() - */ - return(rval); -} - -/* - Remember that when we leave our svc() method, the framework will take care - of calling our close() method so that we can cleanup after ourselves. - */ -int Client_Handler::svc(void) -{ - char buf[128]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - while( 1 ) - { - if( this->process(buf,sizeof(buf)) == -1 ) - { - return(-1); - } - } - - return(0); -} - -/* - Once again, we see that the application-level logic has not been at all affected - by our choice of threading models. Of course, I'm not sharing data between threads - or anything. We'll leave locking issues for a later tutorial. - */ -int Client_Handler::process (char *_rdbuf, int _rdbuf_len) -{ - switch (this->peer ().recv (_rdbuf, _rdbuf_len)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf)); - } - - return 0; -} -</pre> -<HR WIDTH="100%"> - -<P>Ok, now we've gone and changed handle_input() so that it knows when -to do work and when to enqueue itself. Beyond that, we're still about -the same. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page07.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page07.html b/docs/tutorials/007/page07.html deleted file mode 100644 index c4fd555cf68..00000000000 --- a/docs/tutorials/007/page07.html +++ /dev/null @@ -1,197 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Two new files this time. The first is <A HREF="thread_pool.h">thread_pool.h</A> -where we declare our Thread_Pool object. This is responsible for -abstracting away the thread pool implementation details and allowing us -to make so few changes to the rest of the code. - -<P> -<HR WIDTH="100%"><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">// $Id: thread_pool.h,v 1.1 1998/08/30 -16:04:12 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#ifndef THREAD_POOL_H</FONT> -<BR><FONT FACE="Arial,Helvetica">#define THREAD_POOL_H</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> In order to implement a thread -pool, we have to have an object that can create</FONT> -<BR><FONT FACE="Arial,Helvetica"> a thread. The ACE_Task<> -is the basis for doing just such a thing.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "ace/Task.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> We need a forward reference -for ACE_Event_Handler so that our enqueue() method</FONT> -<BR><FONT FACE="Arial,Helvetica"> can accept a pointer to one.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">class ACE_Event_Handler;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Although we modified the -rest of our program to make use of the thread pool</FONT> -<BR><FONT FACE="Arial,Helvetica"> implementation, if you look -closely you'll see that the changes were rather</FONT> -<BR><FONT FACE="Arial,Helvetica"> minor. The "ACE way" -is generally to create a helper object that abstracts</FONT> -<BR><FONT FACE="Arial,Helvetica"> away the details not relevant -to your application. That's what I'm trying</FONT> -<BR><FONT FACE="Arial,Helvetica"> to do here by creating the -Thread_Pool object.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">class Thread_Pool : public ACE_Task<ACE_MT_SYNCH></FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">public:</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Provide an enumeration for the default pool size. By doing this, -other objects</FONT> -<BR><FONT FACE="Arial,Helvetica"> -can use the value when they want a default.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -enum size_t</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -default_pool_size_ = 5</FONT> -<BR><FONT FACE="Arial,Helvetica"> -};</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -// Basic constructor</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Thread_Pool(void);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Opening the thread pool causes one or more threads to be activated. -When activated,</FONT> -<BR><FONT FACE="Arial,Helvetica"> -they all execute the svc() method declared below.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int open( int _pool_size = default_pool_size_ );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -When you're done wit the thread pool, you have to have some way to shut -it down.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -This is what close() is for.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int close(void);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -To use the thread pool, you have to put some unit of work into it. -Since we're</FONT> -<BR><FONT FACE="Arial,Helvetica"> -dealing with event handlers (or at least their derivatives), I've chosen -to provide</FONT> -<BR><FONT FACE="Arial,Helvetica"> -an enqueue() method that takes a pointer to an ACE_Event_Handler. -The handler's</FONT> -<BR><FONT FACE="Arial,Helvetica"> -handle_input() method will be called, so your object has to know when it -is being</FONT> -<BR><FONT FACE="Arial,Helvetica"> -called by the thread pool.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int enqueue( ACE_Event_Handler * _handler );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">protected:</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Our svc() method will dequeue the enqueued event handler objects and invoke -the</FONT> -<BR><FONT FACE="Arial,Helvetica"> -handle_input() method on each. Since we're likely running in more -than one thread,</FONT> -<BR><FONT FACE="Arial,Helvetica"> -idle threads can take work from the queue while other threads are busy -executing</FONT> -<BR><FONT FACE="Arial,Helvetica"> -handle_input() on some object.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int svc(void);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Another handy ACE template is ACE_Atomic_Op<>. When parameterized, -this allows</FONT> -<BR><FONT FACE="Arial,Helvetica"> -is to have a thread-safe counting object. The typical arithmetic -operators are</FONT> -<BR><FONT FACE="Arial,Helvetica"> -all internally thread-safe so that you can share it across threads without -worrying</FONT> -<BR><FONT FACE="Arial,Helvetica"> -about any contention issues.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -typedef ACE_Atomic_Op<ACE_Mutex,int> counter_t;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -We use the atomic op to keep a count of the number of threads in which -our svc()</FONT> -<BR><FONT FACE="Arial,Helvetica"> -method is running. This is particularly important when we want to -close() it down!</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -counter_t active_threads_;</FONT> -<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#endif // THREAD_POOL_H</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P> -<HR WIDTH="100%"> - -<P>Well, that doesn't look too complex. What about the implementation? - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page08.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page08.html b/docs/tutorials/007/page08.html deleted file mode 100644 index 094804e743d..00000000000 --- a/docs/tutorials/007/page08.html +++ /dev/null @@ -1,537 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Finally, <A HREF="thread_pool.cpp">thread_pool.cpp</A> -where we have the Thread_Pool object implementation. - -<P> -<HR WIDTH="100%"> - -<P><FONT FACE="Arial,Helvetica">// $Id: thread_pool.cpp,v 1.1 1998/08/30 -23:47:15 schmidt Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "thread_pool.h"</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> We need this header so that -we can invoke handle_input() on the objects we dequeue.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#include "ace/Event_Handler.h"</FONT> -<BR><FONT FACE="Arial,Helvetica"></FONT> <FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> All we do here is initialize -our active thread counter.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">Thread_Pool::Thread_Pool(void)</FONT> -<BR><FONT FACE="Arial,Helvetica"> : active_threads_(0)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Our open() method is a thin -disguise around the ACE_Task<> activate() method. By</FONT> -<BR><FONT FACE="Arial,Helvetica"> hiding activate() in this -way, the users of Thread_Pool don't have to worry about</FONT> -<BR><FONT FACE="Arial,Helvetica"> the thread configuration -flags.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::open( int _pool_size -)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> return this->activate(THR_NEW_LWP|THR_DETACHED,_pool_size);</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Closing the thread pool can -be a tricky exercise. I've decided to take an easy approach</FONT> -<BR><FONT FACE="Arial,Helvetica"> and simply enqueue a secret -message for each thread we have active.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::close(void)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Find out how many threads are currently active</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -int counter = active_threads_.value();</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -For each one of the active threads, enqueue a "null" event handler. -Below, we'll</FONT> -<BR><FONT FACE="Arial,Helvetica"> -teach our svc() method that "null" means "shutdown".</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -while( counter-- )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -this->enqueue( 0 );</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -As each svc() method exits, it will decrement the active thread counter. -We just wait</FONT> -<BR><FONT FACE="Arial,Helvetica"> -here for it to reach zero. Since we don't know how long it will take, -we sleep for</FONT> -<BR><FONT FACE="Arial,Helvetica"> -a quarter-second or so between tries.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -while( active_threads_.value() )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_OS::sleep( ACE_Time_Value(0.25) );</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -return(0);</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> When an object wants to do -work in the pool, it should call the enqueue() method.</FONT> -<BR><FONT FACE="Arial,Helvetica"> We introduce the ACE_Message_Block -here but, unfortunately, we seriously missuse it.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::enqueue( ACE_Event_Handler -* _handler )</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -An ACE_Message_Block is a chunk of data. You put them into an ACE_Message_Queue.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_Task<> has an ACE_Message_Queue built in. In fact, the parameter -to ACE_Task<></FONT> -<BR><FONT FACE="Arial,Helvetica"> -is passed directly to ACE_Message_Queue. If you look back at our -header file you'll</FONT> -<BR><FONT FACE="Arial,Helvetica"> -see that we used ACE_MT_SYNCH as the parameter indicating that we want -MultiThread</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Synch safety. This allows us to safely put ACE_Message_Block objects -into the</FONT> -<BR><FONT FACE="Arial,Helvetica"> -message queue in one thread and take them out in another.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -An ACE_Message_Block wants to have char* data. We don't have that. -We could</FONT> -<BR><FONT FACE="Arial,Helvetica"> -cast our ACE_Event_Handler* directly to a char* but I wanted to be more -explicit.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Since casting pointers around is a dangerous thing, I've gone out of my -way here</FONT> -<BR><FONT FACE="Arial,Helvetica"> -to be very clear about what we're doing.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -First: Cast the handler pointer to a void pointer. You can't -do any useful work</FONT> -<BR><FONT FACE="Arial,Helvetica"> -on a void pointer, so this is a clear message that we're making the</FONT> -<BR><FONT FACE="Arial,Helvetica"> -pointer unusable.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -Next: Cast the void pointer to a char pointer that the ACE_Message_Block -will accept.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -void * v_data = (void*)_handler;</FONT> -<BR><FONT FACE="Arial,Helvetica"> -char * c_data = (char*)v_data;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Construct a new ACE_Message_Block. For efficiency, you might want -to preallocate a</FONT> -<BR><FONT FACE="Arial,Helvetica"> -stack of these and reuse them. For simplicity, I'll just create what -I need as I need it.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_Message_Block * mb = new ACE_Message_Block( c_data );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Our putq() method is a wrapper around one of the enqueue methods of the -ACE_Message_Queue</FONT> -<BR><FONT FACE="Arial,Helvetica"> -that we own. Like all good methods, it returns -1 if it fails for -some reason.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( this->putq(mb) == -1 )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Another trait of the ACE_Message_Block objects is that they are reference -counted.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Since they're designed to be passed around between various objects in several -threads</FONT> -<BR><FONT FACE="Arial,Helvetica"> -we can't just delete them whenever we feel like it. The release() -method is similar</FONT> -<BR><FONT FACE="Arial,Helvetica"> -to the destroy() method we've used elsewhere. It watches the reference -count and will</FONT> -<BR><FONT FACE="Arial,Helvetica"> -delete the object when possible.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -mb->release();</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return(-1);</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -return(0);</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The "guard" concept is very -powerful and used throughout multi-threaded applications.</FONT> -<BR><FONT FACE="Arial,Helvetica"> A guard normally does some -operation on an object at construction and the "opposite"</FONT> -<BR><FONT FACE="Arial,Helvetica"> operation at destruction. -For instance, when you guard a mutex (lock) object, the guard</FONT> -<BR><FONT FACE="Arial,Helvetica"> will acquire the lock on -construction and release it on destruction. In this way, your</FONT> -<BR><FONT FACE="Arial,Helvetica"> method can simply let the -guard go out of scope and know that the lock is released.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> Guards aren't only useful -for locks however. In this application I've created two guard</FONT> -<BR><FONT FACE="Arial,Helvetica"> objects for quite a different -purpose.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The Counter_Guard is constructed -with a reference to the thread pool's active thread</FONT> -<BR><FONT FACE="Arial,Helvetica"> counter. The guard -increments the counter when it is created and decrements it at</FONT> -<BR><FONT FACE="Arial,Helvetica"> destruction. By creating -one of these in svc(), I know that the counter will be decremented</FONT> -<BR><FONT FACE="Arial,Helvetica"> no matter how or where svc() -returns.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">class Counter_Guard</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">public:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Counter_Guard( Thread_Pool::counter_t & _counter )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -: counter_(_counter)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -++counter_;</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -~Counter_Guard(void)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> ---counter_;</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">protected:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Thread_Pool::counter_t & counter_;</FONT> -<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> My Message_Block_Guard is -also a little non-traditional. It doesn't do anything in the</FONT> -<BR><FONT FACE="Arial,Helvetica"> constructor but it's destructor -ensures that the message block's release() method is called.</FONT> -<BR><FONT FACE="Arial,Helvetica"> This is a cheap way to prevent -a memory leak if I need an additional exit point in svc().</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">class Message_Block_Guard</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">public:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Message_Block_Guard( ACE_Message_Block * & _mb )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -: mb_(_mb)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -~Message_Block_Guard( void )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -mb_->release();</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">protected:</FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_Message_Block * & mb_;</FONT> -<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Now we come to the svc() -method. As I said, this is being executed in each thread of the</FONT> -<BR><FONT FACE="Arial,Helvetica"> Thread_Pool. Here, -we pull messages off of our built-in ACE_Message_Queue and cause them</FONT> -<BR><FONT FACE="Arial,Helvetica"> to do work.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::svc(void)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -The getq() method takes a reference to a pointer. So... we need a -pointer to give it</FONT> -<BR><FONT FACE="Arial,Helvetica"> -a reference to.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_Message_Block * mb;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Create the guard for our active thread counter object. No matter -where we choose to</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return() from svc(), we no know that the counter will be decremented.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Counter_Guard counter_guard(active_threads_);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Get messages from the queue until we have a failure. There's no real -good reason</FONT> -<BR><FONT FACE="Arial,Helvetica"> -for failure so if it happens, we leave immediately.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -while( this->getq(mb) != -1 )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -A successful getq() will cause "mb" to point to a valid refernce-counted</FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_Message_Block. We use our guard object here so that we're sure -to call</FONT> -<BR><FONT FACE="Arial,Helvetica"> -the release() method of that message block and reduce it's reference count.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Once the count reaches zero, it will be deleted.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Message_Block_Guard message_block_guard(mb);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -As noted before, the ACE_Message_Block stores it's data as a char*. -We pull that</FONT> -<BR><FONT FACE="Arial,Helvetica"> -out here and later turn it into an ACE_Event_Handler*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -char * c_data = mb->base();</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -We've chosen to use a "null" value as an indication to leave. If -the data we got</FONT> -<BR><FONT FACE="Arial,Helvetica"> -from the queue is not null then we have some work to do.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( c_data )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Once again, we go to great lengths to emphasize the fact that we're casting -pointers</FONT> -<BR><FONT FACE="Arial,Helvetica"> -around in rather impolite ways. We could have cast the char* directly -to an</FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_Event_Handler* but then folks might think that's an OK thing to do.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -(Note: The correct way to use an ACE_Message_Block is to write data -into it.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -What I should have done was create a message block big enough to hold an</FONT> -<BR><FONT FACE="Arial,Helvetica"> -event handler pointer and then written the pointer value into the block. -When</FONT> -<BR><FONT FACE="Arial,Helvetica"> -we got here, I would have to read that data back into a pointer. -While politically</FONT> -<BR><FONT FACE="Arial,Helvetica"> -correct, it is also a lot of work. If you're careful you can get -away with casting</FONT> -<BR><FONT FACE="Arial,Helvetica"> -pointers around.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -void * v_data = (void*)c_data;</FONT> -<BR><FONT FACE="Arial,Helvetica"> </FONT> -<BR><FONT FACE="Arial,Helvetica"> -ACE_Event_Handler * handler = (ACE_Event_Handler*)v_data;</FONT> -<BR><FONT FACE="Arial,Helvetica"> </FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Now that we finally have an event handler pointer, invoke it's handle_input() -method.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Since we don't know it's handle, we just give it a default. That's -OK because we</FONT> -<BR><FONT FACE="Arial,Helvetica"> -know that we're not using the handle in the method anyway.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( handler->handle_input(ACE_INVALID_HANDLE) == -1 )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Tell the handler that it's time to go home. The "normal" method for -shutting</FONT> -<BR><FONT FACE="Arial,Helvetica"> -down a handler whose handler failed is to invoke handle_close(). -This will</FONT> -<BR><FONT FACE="Arial,Helvetica"> -take care of cleaning it up for us.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Notice how we use the handler's get_handle() method to populate it's "handle"</FONT> -<BR><FONT FACE="Arial,Helvetica"> -parameter. Convenient isn't it?</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -handler->handle_close(handler->get_handle(),0);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Also notice that we don't exit the svc() method here! The first time -I did</FONT> -<BR><FONT FACE="Arial,Helvetica"> -this, I was exiting. After a few clients disconnect you have an empty</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread pool. Hard to do any more work after that...</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT> -<BR><FONT FACE="Arial,Helvetica"> -else</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -If we get here, we were given a message block with "null" data. That -is our</FONT> -<BR><FONT FACE="Arial,Helvetica"> -signal to leave, so we return(0) to leave gracefully.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return(0); -// Ok, shutdown request</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -// message_block_guard goes out of scope here</FONT> -<BR><FONT FACE="Arial,Helvetica"> -// and releases the message_block instance.</FONT> -<BR><FONT FACE="Arial,Helvetica"> -}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> -return(0);</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page09.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/page09.html b/docs/tutorials/007/page09.html deleted file mode 100644 index 00e9ff650b5..00000000000 --- a/docs/tutorials/007/page09.html +++ /dev/null @@ -1,85 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 006</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> - -<HR WIDTH="100%"> - -<P>That's it for Tutorial 7. As with Tutorial 6, we really didn't -have to change much to introduce a new threading strategy. Most of -the work was in creating the Thread_Pool object itself. Everything -else was just minor housekeeping. - -<P>There is a fourth common thread strategy: thread-per-request. -It's not one of my favorites, so I wasn't planning to go into it. -If you want to contribute a tutorial on that topic though, I'll be glad -to include it here. - -<P>For reference, here's the file list again: -<UL> -<LI> -<A HREF="Makefile">Makefile</A></LI> - -<LI> -<A HREF="client_acceptor.h">client_acceptor.h</A></LI> - -<LI> -<A HREF="client_acceptor.cpp">client_acceptor.cpp</A></LI> - -<LI> -<A HREF="client_handler.cpp">client_handler.cpp</A></LI> - -<LI> -<A HREF="client_handler.h">client_handler.h</A></LI> - -<LI> -<A HREF="server.cpp">server.cpp</A></LI> - -<LI> -<A HREF="thread_pool.h">thread_pool.h</A></LI> - -<LI> -<A HREF="thread_pool.cpp">thread_pool.cpp</A></LI> - -<LI> -<A HREF="fix.Makefile">fix.Makefile</A></LI> -</UL> -<P> -<HR WIDTH="100%"> -<P> -<center><h2>Danger, Warning!</h2></center> -Now that I've gone through all of this to create a thread pool server, -I have to point out that this isn't exactly the best or safest way to -do so. The biggest danger we face with this approach is the -possibility of an event handler existing in the thread pool's message -queue <i>after</i> it has been deleted. When the thread's svc() -method attempts to invoke <i>handle_input()</i> you will get a nasty -core dump. -<p> -The safest way to handle the situation is to use reference-counted -pointers everywhere a Client_Handler pointer would be used. That's -beyond the scope of the tutorial but I encourage you to give it a -try. If you want to contribute that back as an enhanced Tutorial, -I'll be glad to include it. -<p> -Another approach that should work quite well is to use the -ACE_TP_Reactor instead of just ACE_Reactor. This takes a little more -setup but results in a cleaner implementation. Again, I've not had -time to develop a Tutorial on the TP_Reactor but would welcome any -contributions. -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/007/server.cpp b/docs/tutorials/007/server.cpp deleted file mode 100644 index 55fb69c58ef..00000000000 --- a/docs/tutorials/007/server.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// $Id$ - -/* - We try to keep main() very simple. One of the ways we do that is to push - much of the complicated stuff into worker objects. In this case, we only - need to include the acceptor header in our main source file. We let it - worry about the "real work". - */ - -#include "client_acceptor.h" - -/* - As before, we create a simple signal handler that will set our finished - flag. There are, of course, more elegant ways to handle program shutdown - requests but that isn't really our focus right now, so we'll just do the - easiest thing. - */ - -static sig_atomic_t finished = 0; -extern "C" void handler (int) -{ - finished = 1; -} - -/* - A server has to listen for clients at a known TCP/IP port. The default ACE - port is 10002 (at least on my system) and that's good enough for what we - want to do here. Obviously, a more robust application would take a command - line parameter or read from a configuration file or do some other clever - thing. Just like the signal handler above, though, that's what we want to - focus on, so we're taking the easy way out. - */ - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* - Finally, we get to main. Some C++ compilers will complain loudly if your - function signature doesn't match the prototype. Even though we're not - going to use the parameters, we still have to specify them. - */ - -int main (int argc, char *argv[]) -{ -/* - In our earlier servers, we used a global pointer to get to the reactor. I've - never really liked that idea, so I've moved it into main() this time. When - we get to the Client_Handler object you'll see how we manage to get a - pointer back to this reactor. - */ - ACE_Reactor reactor; - - /* - The acceptor will take care of letting clients connect to us. It will - also arrange for a Client_Handler to be created for each new client. - Since we're only going to listen at one TCP/IP port, we only need one - acceptor. If we wanted, though, we could create several of these and - listen at several ports. (That's what we would do if we wanted to rewrite - inetd for instance.) - */ - Client_Acceptor peer_acceptor; - - /* - Create an ACE_INET_Addr that represents our endpoint of a connection. We - then open our acceptor object with that Addr. Doing so tells the acceptor - where to listen for connections. Servers generally listen at "well known" - addresses. If not, there must be some mechanism by which the client is - informed of the server's address. - - Note how ACE_ERROR_RETURN is used if we fail to open the acceptor. This - technique is used over and over again in our tutorials. - */ - if (peer_acceptor.open (ACE_INET_Addr (PORT), &reactor) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - - /* - Install our signal handler. You can actually register signal handlers - with the reactor. You might do that when the signal handler is - responsible for performing "real" work. Our simple flag-setter doesn't - justify deriving from ACE_Event_Handler and providing a callback function - though. - */ - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - /* - Like ACE_ERROR_RETURN, the ACE_DEBUG macro gets used quite a bit. It's a - handy way to generate uniform debug output from your program. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n")); - - /* - This will loop "forever" invoking the handle_events() method of our - reactor. handle_events() watches for activity on any registered handlers - and invokes their appropriate callbacks when necessary. Callback-driven - programming is a big thing in ACE, you should get used to it. If the - signal handler catches something, the finished flag will be set and we'll - exit. Conveniently enough, handle_events() is also interrupted by signals - and will exit back to the while() loop. (If you want your event loop to - not be interrupted by signals, checkout the <i>restart</i> flag on the - open() method of ACE_Reactor if you're interested.) - */ - while (!finished) - reactor.handle_events (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server daemon\n")); - - return 0; -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -template class ACE_Guard<ACE_Mutex>; -template class ACE_Atomic_Op<ACE_Mutex, int>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#pragma instantiate ACE_Guard<ACE_Mutex> -#pragma instantiate ACE_Atomic_Op<ACE_Mutex, int> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/docs/tutorials/007/thread_pool.cpp b/docs/tutorials/007/thread_pool.cpp deleted file mode 100644 index 852b51ef232..00000000000 --- a/docs/tutorials/007/thread_pool.cpp +++ /dev/null @@ -1,277 +0,0 @@ - -// $Id$ - -#include "thread_pool.h" - -/* - We need this header so that we can invoke handle_input() on the objects we dequeue. - */ -#include "ace/Event_Handler.h" - - -/* - All we do here is initialize our active thread counter. - */ -Thread_Pool::Thread_Pool(void) - : active_threads_(0) -{ -} - -/* - Our open() method is a thin disguise around the ACE_Task<> activate() method. By - hiding activate() in this way, the users of Thread_Pool don't have to worry about - the thread configuration flags. - */ -int Thread_Pool::open( int _pool_size ) -{ - return this->activate(THR_NEW_LWP,_pool_size); -} - -/* - Closing the thread pool can be a tricky exercise. I've decided to take an easy approach - and simply enqueue a secret message for each thread we have active. - */ -int Thread_Pool::close( u_long flags ) -{ - ACE_UNUSED_ARG(flags); - - /* - Find out how many threads are currently active - */ - int counter = active_threads_.value(); - - /* - For each one of the active threads, enqueue a "null" event handler. Below, we'll - teach our svc() method that "null" means "shutdown". - */ - while( counter-- ) - { - this->enqueue( 0 ); - } - - /* - As each svc() method exits, it will decrement the active thread counter. We just wait - here for it to reach zero. Since we don't know how long it will take, we sleep for - a quarter-second or so between tries. - */ - while( active_threads_.value() ) - { - ACE_OS::sleep( ACE_Time_Value(0.25) ); - } - - return(0); -} - -/* - When an object wants to do work in the pool, it should call the enqueue() method. - We introduce the ACE_Message_Block here but, unfortunately, we seriously missuse it. - */ -int Thread_Pool::enqueue( ACE_Event_Handler * _handler ) -{ - /* - An ACE_Message_Block is a chunk of data. You put them into an ACE_Message_Queue. - ACE_Task<> has an ACE_Message_Queue built in. In fact, the parameter to ACE_Task<> - is passed directly to ACE_Message_Queue. If you look back at our header file you'll - see that we used ACE_MT_SYNCH as the parameter indicating that we want MultiThread - Synch safety. This allows us to safely put ACE_Message_Block objects into the - message queue in one thread and take them out in another. - */ - - /* - An ACE_Message_Block wants to have char* data. We don't have that. We could - cast our ACE_Event_Handler* directly to a char* but I wanted to be more explicit. - Since casting pointers around is a dangerous thing, I've gone out of my way here - to be very clear about what we're doing. - - First: Cast the handler pointer to a void pointer. You can't do any useful work - on a void pointer, so this is a clear message that we're making the - pointer unusable. - - Next: Cast the void pointer to a char pointer that the ACE_Message_Block will accept. - */ - void * v_data = (void*)_handler; - char * c_data = (char*)v_data; - - /* - Construct a new ACE_Message_Block. For efficiency, you might want to preallocate a - stack of these and reuse them. For simplicity, I'll just create what I need as I need it. - */ - ACE_Message_Block * mb = new ACE_Message_Block( c_data ); - - /* - Our putq() method is a wrapper around one of the enqueue methods of the ACE_Message_Queue - that we own. Like all good methods, it returns -1 if it fails for some reason. - */ - if( this->putq(mb) == -1 ) - { - /* - Another trait of the ACE_Message_Block objects is that they are reference counted. - Since they're designed to be passed around between various objects in several threads - we can't just delete them whenever we feel like it. The release() method is similar - to the destroy() method we've used elsewhere. It watches the reference count and will - delete the object when possible. - */ - mb->release(); - return(-1); - } - - return(0); -} - -/* - The "guard" concept is very powerful and used throughout multi-threaded applications. - A guard normally does some operation on an object at construction and the "opposite" - operation at destruction. For instance, when you guard a mutex (lock) object, the guard - will acquire the lock on construction and release it on destruction. In this way, your - method can simply let the guard go out of scope and know that the lock is released. - - Guards aren't only useful for locks however. In this application I've created two guard - objects for quite a different purpose. - */ - -/* - The Counter_Guard is constructed with a reference to the thread pool's active thread - counter. The guard increments the counter when it is created and decrements it at - destruction. By creating one of these in svc(), I know that the counter will be decremented - no matter how or where svc() returns. - */ -class Counter_Guard -{ -public: - Counter_Guard( Thread_Pool::counter_t & _counter ) - : counter_(_counter) - { - ++counter_; - } - - ~Counter_Guard(void) - { - --counter_; - } - -protected: - Thread_Pool::counter_t & counter_; -}; - -/* - My Message_Block_Guard is also a little non-traditional. It doesn't do anything in the - constructor but it's destructor ensures that the message block's release() method is called. - This is a cheap way to prevent a memory leak if I need an additional exit point in svc(). - */ -class Message_Block_Guard -{ -public: - Message_Block_Guard( ACE_Message_Block * & _mb ) - : mb_(_mb) - { - } - - ~Message_Block_Guard( void ) - { - mb_->release(); - } - -protected: - ACE_Message_Block * & mb_; -}; - -/* - Now we come to the svc() method. As I said, this is being executed in each thread of the - Thread_Pool. Here, we pull messages off of our built-in ACE_Message_Queue and cause them - to do work. - */ -int Thread_Pool::svc(void) -{ - /* - The getq() method takes a reference to a pointer. So... we need a pointer to give it - a reference to. - */ - ACE_Message_Block * mb; - - /* - Create the guard for our active thread counter object. No matter where we choose to - return() from svc(), we no know that the counter will be decremented. - */ - Counter_Guard counter_guard(active_threads_); - - /* - Get messages from the queue until we have a failure. There's no real good reason - for failure so if it happens, we leave immediately. - */ - while( this->getq(mb) != -1 ) - { - /* - A successful getq() will cause "mb" to point to a valid refernce-counted - ACE_Message_Block. We use our guard object here so that we're sure to call - the release() method of that message block and reduce it's reference count. - Once the count reaches zero, it will be deleted. - */ - Message_Block_Guard message_block_guard(mb); - - /* - As noted before, the ACE_Message_Block stores it's data as a char*. We pull that - out here and later turn it into an ACE_Event_Handler* - */ - char * c_data = mb->base(); - - /* - We've chosen to use a "null" value as an indication to leave. If the data we got - from the queue is not null then we have some work to do. - */ - if( c_data ) - { - /* - Once again, we go to great lengths to emphasize the fact that we're casting pointers - around in rather impolite ways. We could have cast the char* directly to an - ACE_Event_Handler* but then folks might think that's an OK thing to do. - - (Note: The correct way to use an ACE_Message_Block is to write data into it. - What I should have done was create a message block big enough to hold an - event handler pointer and then written the pointer value into the block. When - we got here, I would have to read that data back into a pointer. While politically - correct, it is also a lot of work. If you're careful you can get away with casting - pointers around.) - */ - void * v_data = (void*)c_data; - - ACE_Event_Handler * handler = (ACE_Event_Handler*)v_data; - - /* - Now that we finally have an event handler pointer, invoke it's handle_input() method. - Since we don't know it's handle, we just give it a default. That's OK because we - know that we're not using the handle in the method anyway. - */ - if( handler->handle_input(ACE_INVALID_HANDLE) == -1 ) - { - /* - Tell the handler that it's time to go home. The "normal" method for shutting - down a handler whose handler failed is to invoke handle_close(). This will - take care of cleaning it up for us. - Notice how we use the handler's get_handle() method to populate it's "handle" - parameter. Convenient isn't it? - */ - handler->handle_close(handler->get_handle(),0); - - /* - Also notice that we don't exit the svc() method here! The first time I did - this, I was exiting. After a few clients disconnect you have an empty - thread pool. Hard to do any more work after that... - */ - } - } - else - { - /* - If we get here, we were given a message block with "null" data. That is our - signal to leave, so we return(0) to leave gracefully. - */ - return(0); // Ok, shutdown request - } - - // message_block_guard goes out of scope here - // and releases the message_block instance. - } - - return(0); -} - diff --git a/docs/tutorials/007/thread_pool.h b/docs/tutorials/007/thread_pool.h deleted file mode 100644 index 12b9f14a44f..00000000000 --- a/docs/tutorials/007/thread_pool.h +++ /dev/null @@ -1,102 +0,0 @@ - -// $Id$ - -#ifndef THREAD_POOL_H -#define THREAD_POOL_H - -/* - In order to implement a thread pool, we have to have an object that can create - a thread. The ACE_Task<> is the basis for doing just such a thing. - */ -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - We need a forward reference for ACE_Event_Handler so that our enqueue() method - can accept a pointer to one. - */ -class ACE_Event_Handler; - -/* - Although we modified the rest of our program to make use of the thread pool - implementation, if you look closely you'll see that the changes were rather - minor. The "ACE way" is generally to create a helper object that abstracts - away the details not relevant to your application. That's what I'm trying - to do here by creating the Thread_Pool object. - */ -class Thread_Pool : public ACE_Task<ACE_MT_SYNCH> -{ -public: - - typedef ACE_Task<ACE_MT_SYNCH> inherited; - - /* - Provide an enumeration for the default pool size. By doing this, other objects - can use the value when they want a default. - */ - enum size_t - { - default_pool_size_ = 5 - }; - - // Basic constructor - Thread_Pool(void); - - /* - Opening the thread pool causes one or more threads to be activated. When activated, - they all execute the svc() method declared below. - */ - int open( int _pool_size = default_pool_size_ ); - - /* - Some compilers will complain that our open() above attempts to - override a virtual function in the baseclass. We have no - intention of overriding that method but in order to keep the - compiler quiet we have to add this method as a pass-thru to the - baseclass method. - */ - virtual int open(void * _void_data) - { return inherited::open(_void_data); } - - /* - */ - int close( u_long flags = 0 ); - - /* - To use the thread pool, you have to put some unit of work into it. Since we're - dealing with event handlers (or at least their derivatives), I've chosen to provide - an enqueue() method that takes a pointer to an ACE_Event_Handler. The handler's - handle_input() method will be called, so your object has to know when it is being - called by the thread pool. - */ - int enqueue( ACE_Event_Handler * _handler ); - - /* - Another handy ACE template is ACE_Atomic_Op<>. When parameterized, this allows - is to have a thread-safe counting object. The typical arithmetic operators are - all internally thread-safe so that you can share it across threads without worrying - about any contention issues. - */ - typedef ACE_Atomic_Op<ACE_Mutex,int> counter_t; - -protected: - - /* - Our svc() method will dequeue the enqueued event handler objects and invoke the - handle_input() method on each. Since we're likely running in more than one thread, - idle threads can take work from the queue while other threads are busy executing - handle_input() on some object. - */ - int svc(void); - - /* - We use the atomic op to keep a count of the number of threads in which our svc() - method is running. This is particularly important when we want to close() it down! - */ - counter_t active_threads_; -}; - -#endif // THREAD_POOL_H diff --git a/docs/tutorials/008/008-broadcast.dsp b/docs/tutorials/008/008-broadcast.dsp deleted file mode 100644 index b7aafc7ba00..00000000000 --- a/docs/tutorials/008/008-broadcast.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="008 broadcast" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=008 broadcast - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "008-broadcast.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "008-broadcast.mak" CFG="008 broadcast - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "008 broadcast - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "008 broadcast - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "008 broadcast - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "008 broadcast - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../broadcast_client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "008 broadcast - Win32 Release"
-# Name "008 broadcast - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=broadcast_client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/008/008-direct.dsp b/docs/tutorials/008/008-direct.dsp deleted file mode 100644 index a8f6d2386ce..00000000000 --- a/docs/tutorials/008/008-direct.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="008 direct" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=008 direct - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "008-direct.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "008-direct.mak" CFG="008 direct - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "008 direct - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "008 direct - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "008 direct - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "008 direct - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../directed_client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "008 direct - Win32 Release"
-# Name "008 direct - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=directed_client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/008/008-server.dsp b/docs/tutorials/008/008-server.dsp deleted file mode 100644 index 8db64b2fa66..00000000000 --- a/docs/tutorials/008/008-server.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="008 server" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=008 server - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "008-server.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "008-server.mak" CFG="008 server - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "008 server - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "008 server - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "008 server - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "008 server - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "008 server - Win32 Release"
-# Name "008 server - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/008/Makefile b/docs/tutorials/008/Makefile deleted file mode 100644 index 0a3070f89db..00000000000 --- a/docs/tutorials/008/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server directed_client broadcast_client - -FILES = - -BUILD = $(VBIN) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -bli0 -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! - - # This is inserted by the fix.Makefile script -include .depend diff --git a/docs/tutorials/008/broadcast_client.cpp b/docs/tutorials/008/broadcast_client.cpp deleted file mode 100644 index 2f754806d03..00000000000 --- a/docs/tutorials/008/broadcast_client.cpp +++ /dev/null @@ -1,72 +0,0 @@ - -// $Id$ - -#include "ace/SOCK_Dgram_Bcast.h" -#include "ace/INET_Addr.h" - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main(int argc,char *argv[] ) -{ - ACE_INET_Addr local((u_short)0); - - /* - Instead of creating the ACE_SOCK_Dgram we created last time, - we'll create an ACE_SOCK_Dgram_Bcast. "Bcast" means, of course, - "Broadcast". This ACE object is clever enough to go out to the - OS and find all of the network interfaces. When you send() - on a Dgram_Bcast, it will send the datagram out on all of those - interfaces. This is quiet handy if you do it on a multi-homed - host that plays router... - */ - ACE_SOCK_Dgram_Bcast dgram; - - if( dgram.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1); - } - - char buf[512]; - - sprintf(buf, "Hello World!"); - - /* - The only other difference between us and the directed client - is that we don't specify a host to receive the datagram. - Instead, we use the magic value "INADDR_BROADCAST". All hosts - are obliged to respond to datagrams directed to this address - the same as they would to datagrams sent to their hostname. - - Remember, the Dgram_Bcast will send a datagram to all interfaces - on the host. That's true even if the address is for a specific - host (and the host address makes sense for the interface). - The real power is in using an INADDR_BROADCAST addressed datagram - against all interfaces. - */ - - ACE_INET_Addr remote(PORT,INADDR_BROADCAST); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Sending (%s) to the server.\n",buf)); - - if( dgram.send(buf,strlen(buf)+1,remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1); - } - - if( dgram.recv(buf,sizeof(buf),remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1); - } - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server said: %s\n",buf)); - - /* - Using the "remote" object instance, find out where the server lives. - We could then save this address and use directed datagrams to chat - with the server for a while. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server can be found at: (%s:%d)\n", - remote.get_host_name(), PORT )); - - return(0); -} diff --git a/docs/tutorials/008/directed_client.cpp b/docs/tutorials/008/directed_client.cpp deleted file mode 100644 index 7fac216dbc3..00000000000 --- a/docs/tutorials/008/directed_client.cpp +++ /dev/null @@ -1,112 +0,0 @@ - -// $Id$ - -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -/* - Once again, we use the default server port. In a "real" system, - the server's port (or ports) would be published in some way so - that clients would know where to "look". We could even add entries - to the operating system's services file and use a service name - instead of a number. We'll come back to that in some other tutorial - though. For now, let's stay simple. - */ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* - Our goal here is to develop a client that can send a datagram to - a server running on a known host. We'll use a command-line argument - to specify the hostname instead of hard-coding it. - */ -int main(int argc,char *argv[] ) -{ - /* - All datagrams have to have a point of origin. Since we intend to - transmit instead of receive, we initialize an address with zero - and let the OS choose a port for us. We could have chosen our - own value between 1025 and 65535 as long as it isn't already in use. - */ - ACE_INET_Addr local((u_short)0); - - /* - And here is our datagram object. - */ - ACE_SOCK_Dgram dgram; - - /* - Notice that this looks a lot like the server application. There's - no difference in creating server datagrams an client datagrams. - You can even use a zero-constructed address for your server datagram - as long as you tell the client where you're listening (eg -- by writting - into a file or some such). - */ - if( dgram.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1); - } - - /* - Yep. We've seen this before too... - */ - char buf[512]; - - /* - Ok, now we're doing something different. - */ - sprintf(buf, "Hello World!"); - - /* - Just like sending a telegram, we have to address our datagram. - Here, we create an address object at the desired port on the - chosen host. To keep us from crashing, we'll provide a default - host name if we aren't given one. - */ - ACE_INET_Addr remote(PORT, argc > 1 ? argv[1] : "localhost" ); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Sending (%s) to the server.\n",buf)); - /* - Now we send our buffer of stuff to the remote address. This is - just exactly what the server did after receiving a client message. - Datagrams are rather orthogonal that way: they don't generally make - much of a fuss about being either client or server. - */ - if( dgram.send(buf,strlen(buf)+1,remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1); - } - - /* - Now we've turned around and put ourselves into "server mode" by - invoking the recv() method. We now our server is going to send - us something, so we hang out here and wait for it. Because we - know datagrams are unreliable, there is a chance that the server - will respond but we won't hear. You might consider providing a - timeout on the recv() in that case. If recv() fails due to timeout - it will return -1 and you can then resend your query and attempt - the recv() again. - - Like the server application, we have to give the recv() an - uninitialized addr object so that we can find out who is talking - back to us. - */ - if( dgram.recv(buf,sizeof(buf),remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1); - } - - /* - Find out what the server had to say. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server said: %s\n",buf)); - - /* - Using the "remote" object instance, find out where the server lives. - We could then save this address and use directed datagrams to chat - with the server for a while. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server can be found at: (%s:%d)\n", - remote.get_host_name(), PORT )); - - return(0); -} diff --git a/docs/tutorials/008/page01.html b/docs/tutorials/008/page01.html deleted file mode 100644 index ebe24e9ecc8..00000000000 --- a/docs/tutorials/008/page01.html +++ /dev/null @@ -1,60 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In a lot of IPC programming, the clients know where the servers -are. A mail client, for instance, has a configuration file that says -where the mail host is. Your web browser has a "location" field that -you type into to give it a destination. - -<P>What if you have written a server application and then you execute it -on several systems in your network? All of the instances are probably -more or less equal to the client's point of view, so you don't want to -"configure" the clients to a single server each. Likewise, you -want the ability to add and remove servers at any time so you can't just -give the clients a list to choose from. - -<P>So... how do the clients know where the servers are? - -<P>Let 'em ask! - -<P>Datagrams are great for this. You can toss a datagram out onto -the network and any servers listening at the correct port will* hear it. -Like ACE_SOCK_Stream that we've seen before, you can get the peer address -from a datagram. With that, the server can send a response -back to the client. The client, in turn, can pull the peer address -out and know exactly where the server lives. - -<P>In this tutorial we'll develop three applications: a server listening -for datagrams, a client that can send to a known host and a client that -can send to the entire (sub)network. In the next tutorial, we'll -expand on this to make the server a bit more prudish. -<BR> - -<P><FONT SIZE=-1>* Actually, the servers <I>might</I> hear the datagram. -Datagrams are rather unreliable. (Sort of like some operating systems -I know.) Still, if the network traffic isn't too bad, they generally -get through. Your clients can always send out more queries if there -aren't any responses in a timely fashion.</FONT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page02.html b/docs/tutorials/008/page02.html deleted file mode 100644 index 883fe9e857c..00000000000 --- a/docs/tutorials/008/page02.html +++ /dev/null @@ -1,237 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>The first thing we want to look at is <A HREF="server.cpp">server.cpp</A>. -This is a pretty simple application that listens for datagrams at a known -port and sends back a response. In order to implement a true "discovery" -mechanism, the server will have to be a little bit more picky about who -it responds to. We'll tackle that issue in the next tutorial though... - -<P> -<HR WIDTH="100%"> - -<P><TT>/*</TT> -<BR><TT> Our datagram server will, of course, need to create -a datagram.</TT> -<BR><TT> We'll also need an address object so that we know -where to listen.</TT> -<BR><TT> */</TT> -<BR><TT>#include "ace/SOCK_Dgram.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT> - -<P><TT>/*</TT> -<BR><TT> Use the typical TCP/IP port address for receiving -datagrams.</TT> -<BR><TT> */</TT> -<BR><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT> - -<P><TT>int main(int,char**)</TT> -<BR><TT>{</TT> -<BR><TT> /*</TT> -<BR><TT> This is where we'll listen -for datagrams coming from the</TT> -<BR><TT> clients. We'll give -this address to the open() method</TT> -<BR><TT> below to enable the listener.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr local(PORT);</TT> - -<P><TT> /*</TT> -<BR><TT> A simply constructed datagram -that we'll listen with.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_SOCK_Dgram dgram;</TT> - -<P><TT> /*</TT> -<BR><TT> Like most ACE objects, the -datagram has to be opened before</TT> -<BR><TT> it can be uses. Of course, --1 on failure.</TT> - -<P><TT> A datagram will fail to open -if there is already a datagram</TT> -<BR><TT> listening at the port we've -chosen. It *is* OK to open</TT> -<BR><TT> a datagram at a port where -there is an ACE_SOCK_Stream</TT> -<BR><TT> though. This is because -datagrams are UDP and SOCK_Stream</TT> -<BR><TT> is TCP and the two don't cross -paths.</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.open(local) == -1 )</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, -"%p\n", "open"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Create a simple buffer to -receive the data. You generally need</TT> -<BR><TT> to provide a buffer big enough -for the largest datagram you</TT> -<BR><TT> expect to receive. Some -platforms will let you read a little</TT> -<BR><TT> and then some more later but -other platforms will throw out</TT> -<BR><TT> whatever part of the datagram -you don't get with the first</TT> -<BR><TT> read. (This is on a -per-datagram basis BTW.) The theoretical</TT> -<BR><TT> limit on a datagram is about -64k. The realistic limit (because</TT> -<BR><TT> of routers & such) is -much smaller. Choose your buffer size</TT> -<BR><TT> based on your application's -needs.</TT> -<BR><TT> */</TT> -<BR><TT> char buf[512];</TT> - -<P><TT> /*</TT> -<BR><TT> Unlike ACE_SOCK_Stream, datagrams -are unconnected. That is,</TT> -<BR><TT> there is no "virtual circuit" -between server and client.</TT> -<BR><TT> Because of this, the server -has to provide a placeholder</TT> -<BR><TT> for the OS to fill in the -source (client) address information</TT> -<BR><TT> on the recv. You can -initialize this INET_Addr to anything,</TT> -<BR><TT> it will be overwritten when -the data arrives.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr remote;</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server -daemon\n"));</TT> - -<P><TT> /*</TT> -<BR><TT> Receive datagrams as long -as we're able.</TT> -<BR><TT> */</TT> -<BR><TT> while( dgram.recv(buf,sizeof(buf),remote) != --1 )</TT> -<BR><TT> {</TT> -<BR><TT> /*</TT> -<BR><TT> Display -a brief message about our progress. Notice how we</TT> -<BR><TT> use -the 'remote' object to display the address of the client.</TT> -<BR><TT> With -an ACE_SOCK_Stream we used get_remote_addr() to get the</TT> -<BR><TT> address -the socket is connected to. Because datagrams are</TT> -<BR><TT> unconnected, -we use the addr object provided to recv().</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) Data (%s) from client (%s)\n", buf, remote.get_host_name()));</TT> - -<P><TT> /*</TT> -<BR><TT> To -respond to the client's query, we have to become a client</TT> -<BR><TT> ourselves. -To do so, we need an anonymous local address from</TT> -<BR><TT> which -we'll send the response and a datagram in which to send</TT> -<BR><TT> it. -(An anonymous address is simply one where we let the OS</TT> -<BR><TT> choose -a port for us. We really don't care what it is.O</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -local((u_short)0);</TT> -<BR><TT> ACE_SOCK_Dgram client;</TT> - -<P><TT> /*</TT> -<BR><TT> Open -up our response datagram as always.</TT> -<BR><TT> */</TT> -<BR><TT> if( client.open(local) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "client open"),-1);</TT> -<BR><TT> -return(0);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Build -a witty response...</TT> -<BR><TT> */</TT> -<BR><TT> sprintf(buf,"I am here");</TT> - -<P><TT> /*</TT> -<BR><TT> and -send it to the client. Notice the symetry with the recv()</TT> -<BR><TT> method. -Again, the unconnected nature of datagrams forces</TT> -<BR><TT> us -to specify an address object with each read/write operation.</TT> -<BR><TT> In -the case of read (recv()) that's where the OS stuffs the</TT> -<BR><TT> address -of the datagram sender. In the case of write (send())</TT> -<BR><TT> that -we're doing here, the address is where we want the network</TT> -<BR><TT> to -deliver the data.</TT> - -<P><TT> Of -course, we're assuming that the client will be listening</TT> -<BR><TT> for -our reply...</TT> -<BR><TT> */</TT> -<BR><TT> if( client.send(buf,strlen(buf)+1,remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1);</TT> -<BR><TT> -return(0);</TT> -<BR><TT> }</TT> -<BR><TT> }</TT> - -<P><TT> return(0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> - -<P>And that's really all there is to it. Obviously there is some -room for improvement. The most blatant is the somewhat small buffer -size for receiving the datagram. I've never been able to get a solid -answer on datagram sizes. The theoretical limit is just under 64k -but you have to deal with fragmentation. Some readings indicate that -8k is a reasonable size, others go much smaller. My general rule -of thumb is to keep datagrams relatively small (eg -- under 8k or so) and -test a lot. If you find that your routers are fragmenting your larger -datagrams, back off to something smaller. Of course, if you must -send 100k and can only do so 1k at a time, you'll have to worry about retransmissions -& reordering. At that point, you might consider going to TCP. -Remember: datagrams are unreliable! Don't try to make 'em do -something they werent' designed for! - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page03.html b/docs/tutorials/008/page03.html deleted file mode 100644 index 94880dcab71..00000000000 --- a/docs/tutorials/008/page03.html +++ /dev/null @@ -1,187 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In <A HREF="directed_client.cpp">directed_client.cpp</A> we create a -client that knows how to send a datagram to a server on a known host. -This is a good thing if you know where the server lives and want to have -a conversation. The Unix <I>talk</I> utilitiy, for instance, -could be written this way. - -<P> -<HR WIDTH="100%"> - -<P><TT>#include "ace/SOCK_Dgram.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT> - -<P><TT>/*</TT> -<BR><TT> Once again, we use the default server port. -In a "real" system,</TT> -<BR><TT> the server's port (or ports) would be published in -some way so</TT> -<BR><TT> that clients would know where to "look". We -could even add entries</TT> -<BR><TT> to the operating system's services file and use a -service name</TT> -<BR><TT> instead of a number. We'll come back to that -in some other tutorial</TT> -<BR><TT> though. For now, let's stay simple.</TT> -<BR><TT> */</TT> -<BR><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT> - -<P><TT>/*</TT> -<BR><TT> Our goal here is to develop a client that can send -a datagram to</TT> -<BR><TT> a server running on a known host. We'll use -a command-line argument</TT> -<BR><TT> to specify the hostname instead of hard-coding it.</TT> -<BR><TT> */</TT> -<BR><TT>int main(int argc,char *argv[] )</TT> -<BR><TT>{</TT> -<BR><TT> /*</TT> -<BR><TT> All -datagrams have to have a point of origin. Since we intend to</TT> -<BR><TT> transmit -instead of receive, we initialize an address with zero</TT> -<BR><TT> and -let the OS choose a port for us. We could have chosen our</TT> -<BR><TT> own -value between 1025 and 65535 as long as it isn't already in use.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -local((u_short)0);</TT> - -<P><TT> /*</TT> -<BR><TT> And -here is our datagram object.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_SOCK_Dgram dgram;</TT> -<BR><TT> </TT> -<BR><TT> /*</TT> -<BR><TT> Notice -that this looks a lot like the server application. There's</TT> -<BR><TT> no -difference in creating server datagrams an client datagrams.</TT> -<BR><TT> You -can even use a zero-constructed address for your server datagram</TT> -<BR><TT> as -long as you tell the client where you're listening (eg -- by writting</TT> -<BR><TT> into -a file or some such).</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.open(local) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Yep. -We've seen this before too...</TT> -<BR><TT> */</TT> -<BR><TT> char buf[512];</TT> - -<P><TT> /*</TT> -<BR><TT> Ok, -now we're doing something different.</TT> -<BR><TT> */</TT> -<BR><TT> sprintf(buf, "Hello -World!");</TT> - -<P><TT> /*</TT> -<BR><TT> Just -like sending a telegram, we have to address our datagram.</TT> -<BR><TT> Here, -we create an address object at the desired port on the</TT> -<BR><TT> chosen -host. To keep us from crashing, we'll provide a default</TT> -<BR><TT> host -name if we aren't given one.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -remote(PORT, argc > 1 ? argv[1] : "localhost" );</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) Sending (%s) to the server.\n",buf));</TT> -<BR><TT> /*</TT> -<BR><TT> -Now we send our buffer of stuff to the remote address. This is</TT> -<BR><TT> -just exactly what the server did after receiving a client message.</TT> -<BR><TT> -Datagrams are rather orthogonal that way: they don't generally make</TT> -<BR><TT> -much of a fuss about being either client or server.</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.send(buf,strlen(buf)+1,remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Now -we've turned around and put ourselves into "server mode" by</TT> -<BR><TT> invoking -the recv() method. We now our server is going to send</TT> -<BR><TT> us -something, so we hang out here and wait for it. Because we</TT> -<BR><TT> know -datagrams are unreliable, there is a chance that the server</TT> -<BR><TT> will -respond but we won't hear. You might consider providing a</TT> -<BR><TT> timeout -on the recv() in that case. If recv() fails due to timeout</TT> -<BR><TT> it -will return -1 and you can then resend your query and attempt</TT> -<BR><TT> the -recv() again.</TT> -<BR><TT> */</TT> -<BR><TT> if( dgram.recv(buf,sizeof(buf),remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> /*</TT> -<BR><TT> Find -out what the server had to say.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) The server said: %s\n",buf));</TT> - -<P><TT> return(0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> - -<P>That's all neat and good but the point of what we're doing here is not -to talk to a server we know about but to discover servers we don't know -about. Now, you could send a directed datagram to every possible -host address on your network but that's not a very nice thing to do. -On the next page, we'll find out the right approach... - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page04.html b/docs/tutorials/008/page04.html deleted file mode 100644 index e52d37d19c7..00000000000 --- a/docs/tutorials/008/page04.html +++ /dev/null @@ -1,156 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<BR> -<BR> In <A HREF="broadcast_client.cpp">broadcast_client.cpp</A> we -find out how to send a single datagram to every host on our (sub)network. -I have to say <I>(sub)network</I> because broadcast datagrams typically -are not passed through routers. So, if your network admin has divided -up your network into subnets, your broadcasts will likey only stay on the -subnet you're a part of. - -<P>I've only commented the parts that are different from the directed_client. - -<P> -<HR WIDTH="100%"> - -<P><TT>#include "ace/SOCK_Dgram_Bcast.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT> - -<P><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT> - -<P><TT>int main(int argc,char *argv[] )</TT> -<BR><TT>{</TT> -<BR><TT> ACE_INET_Addr -local((u_short)0);</TT> - -<P><TT> /*</TT> -<BR><TT> Instead -of creating the ACE_SOCK_Dgram we created last time,</TT> -<BR><TT> we'll -create an ACE_SOCK_Dgram_Bcast. "Bcast" means, of course,</TT> -<BR><TT> "Broadcast". -This ACE object is clever enough to go out to the</TT> -<BR><TT> OS -and find all of the network interfaces. When you send()</TT> -<BR><TT> on -a Dgram_Bcast, it will send the datagram out on all of those</TT> -<BR><TT> interfaces. -This is quiet handy if you do it on a multi-homed</TT> -<BR><TT> host -that plays router...</TT> -<BR><TT> */</TT> -<BR><TT> ACE_SOCK_Dgram_Bcast -dgram;</TT> - -<P><TT> if( dgram.open(local) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "datagram open"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> char buf[512];</TT> - -<P><TT> sprintf(buf, "Hello World!");</TT> - -<P><TT> /*</TT> -<BR><TT> The -only other difference between us and the directed client</TT> -<BR><TT> is -that we don't specify a host to receive the datagram.</TT> -<BR><TT> Instead, -we use the magic value "INADDR_BROADCAST". All hosts</TT> -<BR><TT> are -obliged to respond to datagrams directed to this address</TT> -<BR><TT> the -same as they would to datagrams sent to their hostname.</TT> - -<P><TT> Remember, -the Dgram_Bcast will send a datagram to all interfaces</TT> -<BR><TT> on -the host. That's true even if the address is for a specific</TT> -<BR><TT> host -(and the host address makes sense for the interface).</TT> -<BR><TT> The -real power is in using an INADDR_BROADCAST addressed datagram</TT> -<BR><TT> against -all interfaces.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_INET_Addr -remote(PORT,INADDR_BROADCAST);</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) Sending (%s) to the server.\n",buf));</TT> -<BR><TT> </TT> -<BR><TT> if( dgram.send(buf,strlen(buf)+1,remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> if( dgram.recv(buf,sizeof(buf),remote) -== -1 )</TT> -<BR><TT> {</TT> -<BR><TT> -ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"),-1);</TT> -<BR><TT> }</TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) The server said: %s\n",buf));</TT> - -<P><TT> /*</TT> -<BR><TT> Using -the <I>remote</I> object instance, find out where the server lives.</TT> -<BR><TT> We -could then save this address and use directed datagrams to chat</TT> -<BR><TT> with -the server for a while.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG, -"(%P|%t) The server can be found at: (%s:%d)\n",</TT> -<BR><TT> -remote.get_host_addr(), PORT ));</TT> -<BR><TT> </TT> -<BR><TT> return(0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> - -<P> About that subnet thing: -<BLOCKQUOTE>If you run this client on a host that has multiple network -interfaces, the broadcast will go to all of those (sub)networks. -What do you do, though, if you need to get past a router? My advice -is to write a server that will run on hosts on both sides of your router. -When a server on one side of the router receives a broadcast, it would -send a directed datagram to it's counterpart on the other side of the router. -The counterpart would then re-broadcast the original datagram on that sub-net. -Cheap, simple and effective.</BLOCKQUOTE> -One final word of warning: -<BLOCKQUOTE>When creating your broadcast datagrams you may see something -like this: <I>ACE_SOCK_Dgram_Bcast::mk_broadcast: Broadcast is not -enable for this interface.: Unknown error</I>. There are some interfaces -(ppp, slip) that don't support broadcast datagrams. That's what you're -seeing here.</BLOCKQUOTE> - -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/page05.html b/docs/tutorials/008/page05.html deleted file mode 100644 index 92b6bbbcfc1..00000000000 --- a/docs/tutorials/008/page05.html +++ /dev/null @@ -1,43 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (WinNT; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 008</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 008</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<BR> -<BR>That's it for this tutorial. In the next one we'll add some intelligence -to the data put into the datagrams. By doing so, we'll be able to -classify our clients and servers into groups. By combining the data -content and the server's port we can get fairly fine-grained control over -who talks to who. - -<P>For you convenience: -<UL> -<LI> -<A HREF="server.cpp">server.cpp</A></LI> - -<LI> -<A HREF="directed_client.cpp">directed_client.cpp</A></LI> - -<LI> -<A HREF="broadcast_client.cpp">broadcast_client.cpp</A></LI> - -<LI> -<A HREF="Makefile">Makefile</A></LI> -</UL> - -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/008/server.cpp b/docs/tutorials/008/server.cpp deleted file mode 100644 index e702b1b93bb..00000000000 --- a/docs/tutorials/008/server.cpp +++ /dev/null @@ -1,128 +0,0 @@ - -// $Id$ - -/* - Our datagram server will, of course, need to create a datagram. - We'll also need an address object so that we know where to listen. - */ -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -/* - Use the typical TCP/IP port address for receiving datagrams. - */ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main(int,char**) -{ - /* - This is where we'll listen for datagrams coming from the - clients. We'll give this address to the open() method - below to enable the listener. - */ - ACE_INET_Addr local(PORT); - - /* - A simply constructed datagram that we'll listen with. - */ - ACE_SOCK_Dgram dgram; - - /* - Like most ACE objects, the datagram has to be opened before - it can be uses. Of course, -1 on failure. - - A datagram will fail to open if there is already a datagram - listening at the port we've chosen. It *is* OK to open - a datagram at a port where there is an ACE_SOCK_Stream - though. This is because datagrams are UDP and SOCK_Stream - is TCP and the two don't cross paths. - */ - if( dgram.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"),-1); - } - - /* - Create a simple buffer to receive the data. You generally need - to provide a buffer big enough for the largest datagram you - expect to receive. Some platforms will let you read a little - and then some more later but other platforms will throw out - whatever part of the datagram you don't get with the first - read. (This is on a per-datagram basis BTW.) The theoretical - limit on a datagram is about 64k. The realistic limit (because - of routers & such) is much smaller. Choose your buffer size - based on your application's needs. - */ - char buf[512]; - - /* - Unlike ACE_SOCK_Stream, datagrams are unconnected. That is, - there is no "virtual circuit" between server and client. - Because of this, the server has to provide a placeholder - for the OS to fill in the source (client) address information - on the recv. You can initialize this INET_Addr to anything, - it will be overwritten when the data arrives. - */ - ACE_INET_Addr remote; - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n")); - - /* - Receive datagrams as long as we're able. - */ - while( dgram.recv(buf,sizeof(buf),remote) != -1 ) - { - /* - Display a brief message about our progress. Notice how we - use the 'remote' object to display the address of the client. - With an ACE_SOCK_Stream we used get_remote_addr() to get the - address the socket is connected to. Because datagrams are - unconnected, we use the addr object provided to recv(). - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data (%s) from client (%s)\n", buf, remote.get_host_name())); - - /* - To respond to the client's query, we have to become a client - ourselves. To do so, we need an anonymous local address from - which we'll send the response and a datagram in which to send - it. (An anonymous address is simply one where we let the OS - choose a port for us. We really don't care what it is.O - */ - ACE_INET_Addr local((u_short)0); - ACE_SOCK_Dgram client; - - /* - Open up our response datagram as always. - */ - if( client.open(local) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "client open"),-1); - return(0); - } - - /* - Build a witty response... - */ - sprintf(buf,"I am here"); - - /* - and send it to the client. Notice the symetry with the recv() - method. Again, the unconnected nature of datagrams forces - us to specify an address object with each read/write operation. - In the case of read (recv()) that's where the OS stuffs the - address of the datagram sender. In the case of write (send()) - that we're doing here, the address is where we want the network - to deliver the data. - - Of course, we're assuming that the client will be listening - for our reply... - */ - if( client.send(buf,strlen(buf)+1,remote) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"),-1); - return(0); - } - } - - return(0); -} diff --git a/docs/tutorials/009/009-broadcast.dsp b/docs/tutorials/009/009-broadcast.dsp deleted file mode 100644 index 14867d087a4..00000000000 --- a/docs/tutorials/009/009-broadcast.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="009 broadcast" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=009 broadcast - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "009-broadcast.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "009-broadcast.mak" CFG="009 broadcast - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "009 broadcast - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "009 broadcast - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "009 broadcast - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "009 broadcast - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../broadcast_client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "009 broadcast - Win32 Release"
-# Name "009 broadcast - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=broadcast_client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/009/009-directed.dsp b/docs/tutorials/009/009-directed.dsp deleted file mode 100644 index a2d80670af8..00000000000 --- a/docs/tutorials/009/009-directed.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="009 directed" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=009 directed - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "009-directed.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "009-directed.mak" CFG="009 directed - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "009 directed - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "009 directed - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "009 directed - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "009 directed - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../directed_client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "009 directed - Win32 Release"
-# Name "009 directed - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=directed_client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/009/009-server.dsp b/docs/tutorials/009/009-server.dsp deleted file mode 100644 index 051b3e9f357..00000000000 --- a/docs/tutorials/009/009-server.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="009 server" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=009 server - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "009-server.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "009-server.mak" CFG="009 server - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "009 server - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "009 server - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "009 server - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "009 server - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "009 server - Win32 Release"
-# Name "009 server - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/009/Makefile b/docs/tutorials/009/Makefile deleted file mode 100644 index 0a3070f89db..00000000000 --- a/docs/tutorials/009/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server directed_client broadcast_client - -FILES = - -BUILD = $(VBIN) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -bli0 -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! - - # This is inserted by the fix.Makefile script -include .depend diff --git a/docs/tutorials/009/broadcast_client.cpp b/docs/tutorials/009/broadcast_client.cpp deleted file mode 100644 index 76ff454d066..00000000000 --- a/docs/tutorials/009/broadcast_client.cpp +++ /dev/null @@ -1,39 +0,0 @@ - -// $Id$ - -#include "ace/SOCK_Dgram_Bcast.h" -#include "ace/INET_Addr.h" - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int argc, char *argv[]) -{ - ACE_INET_Addr local ((u_short) 0); - ACE_INET_Addr remote (PORT, INADDR_BROADCAST); - ACE_SOCK_Dgram_Bcast dgram; - - if (dgram.open (local) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - char buf[512]; - - sprintf (buf, argc > 1 ? argv[1] : "Hello World!"); - - if (dgram.send (buf, strlen (buf) + 1, remote) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); - } - - ACE_Time_Value timeout (2, 0); - if (dgram.recv (buf, sizeof (buf), remote, 0, &timeout) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), -1); - } - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server at (%s) said (%s)\n", - remote.get_host_name (), buf)); - - return (0); -} diff --git a/docs/tutorials/009/directed_client.cpp b/docs/tutorials/009/directed_client.cpp deleted file mode 100644 index 7156286bec1..00000000000 --- a/docs/tutorials/009/directed_client.cpp +++ /dev/null @@ -1,52 +0,0 @@ - -// $Id$ - -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int argc, char *argv[]) -{ - ACE_INET_Addr local ((u_short) 0); - ACE_INET_Addr remote (PORT, argc > 1 ? argv[1] : "localhost"); - ACE_SOCK_Dgram dgram; - - if (dgram.open (local) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - char buf[512]; - - /* - In order to conform to the "protocol" requried by the server, - we allow the user to specify a signature. A default matching - the server's default is also available. - */ - sprintf (buf, argc > 2 ? argv[2] : "Hello World!"); - - if (dgram.send (buf, strlen (buf) + 1, remote) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); - } - - /* - Because we may have sent a signature that the server doesn't - honor, we have to have some way to get out of the recv(). - Most ACE objects that have potential for infinite blocking - give you the option of providing a timeout. recv() is no - exception. Here, we construct an ACE_Time_Value representing - two seconds and no micro-seconds. If recv() fails to get - a response within the two seconds, it will return -1. - */ - ACE_Time_Value timeout (2, 0); - if (dgram.recv (buf, sizeof (buf), remote, 0, &timeout) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), -1); - } - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server said (%s)\n", buf)); - - return (0); -} diff --git a/docs/tutorials/009/page01.html b/docs/tutorials/009/page01.html deleted file mode 100644 index aa80ca05b7c..00000000000 --- a/docs/tutorials/009/page01.html +++ /dev/null @@ -1,52 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 009</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 009</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams again</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In our previous tutorial, we created a datagram listener and a couple -of clients that would send it datagrams. That server would respond -to any datagram sent to the TCP/IP port at which the server was listening. -What we really want to do, however, is to have the server only respond -to clients that meet some criteria. - -<P>Why is this important? - -<P>Imagine you're writting a distributed system that will have many server -applications. Each of those will probably listen at different (and -well-known) TCP/IP addresses so that clients can find each server -without confusion. However... In a large system you might have -several <I>versions</I> of the same server running at the same time*. -You probably don't want those servers running at different addresses since -that breaks the well-known address requirement. - -<P>By creating a datagram listener similar to the last tutorial, a client -can send broadcast datagrams to locate all of the servers listening at -the well-known address. By adding a thin protocol layer into -the datagram contents, the servers can be selective about which clients -they respond to. Thus, if each client sends its version signature -in the broadcast, then the servers can choose to respond only to clients -with matching versions. - -<P><FONT SIZE=-1>*Note: I'm making the assumption that your multiple -server versions will be running on different hosts since you can only have -one server listening at the well-known address on a given host.</FONT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/009/page02.html b/docs/tutorials/009/page02.html deleted file mode 100644 index 1098bef0f46..00000000000 --- a/docs/tutorials/009/page02.html +++ /dev/null @@ -1,130 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 009</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 009</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams again</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Let's take a look at our new <A HREF="server.cpp">server.cpp</A> where -we add in just a bit of code to examine the datagram contents before responding. - -<P> -<HR WIDTH="100%"><TT></TT> - -<P><TT>/*</TT> -<BR><TT> The actual datagram operations here are exactly the -same as those used in</TT> -<BR><TT> the previous tutorial. What we've added is some -logic that will prevent</TT> -<BR><TT> this server from responding to just any old datagram. -I'll limit my</TT> -<BR><TT> comments to those pieces of code.</TT> -<BR><TT> */</TT><TT></TT> - -<P><TT>#include "ace/SOCK_Dgram.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT><TT></TT> - -<P><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT><TT></TT> - -<P><TT>/*</TT> -<BR><TT> In order to be more selective, our server will be -started with a</TT> -<BR><TT> "signature". If none is given, we'll use the -one here instead.</TT> -<BR><TT> */</TT> -<BR><TT>static const char *default_signature = "Hello World!";</TT><TT></TT> - -<P><TT>int main (int argc, char *argv[])</TT> -<BR><TT>{</TT> -<BR><TT> ACE_INET_Addr local (PORT);</TT> -<BR><TT> ACE_SOCK_Dgram dgram;</TT><TT></TT> - -<P><TT> if (dgram.open (local) == -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), --1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> char buf[512];</TT> -<BR><TT> ACE_INET_Addr remote;</TT><TT></TT> - -<P><TT> while (dgram.recv (buf, sizeof (buf), remote) != -1)</TT> -<BR><TT> {</TT> -<BR><TT> /*</TT> -<BR><TT> What did the client say?</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG, "(%P|%t) Received (%s) -from (%s)\n", buf, remote.get_host_name ()));</TT><TT></TT> - -<P><TT> /*</TT> -<BR><TT> Use a simple string-op to -decide if the client is one of our own. Of</TT> -<BR><TT> course, you could have sent -numeric values or even a struct of data. For</TT> -<BR><TT> this simple exercise, however, -strings are just fine.</TT> -<BR><TT> */</TT> -<BR><TT> if (ACE_OS::strcmp (buf, argc > 1 ? argv[1] -: default_signature))</TT> -<BR><TT> {</TT> -<BR><TT> /*</TT> -<BR><TT> If the client -didn't say something we like then log it and move on.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_DEBUG ((LM_DEBUG,</TT> -<BR><TT> -"(%P|%t) Client query does not match our signature (%s). Response -not sent.\n",</TT> -<BR><TT> -argc > 1 ? argv[1] : default_signature));</TT> -<BR><TT> }</TT> -<BR><TT> else</TT> -<BR><TT> {</TT> -<BR><TT> /*</TT> -<BR><TT> As before, we -respond to the client's query.</TT> -<BR><TT> */</TT><TT></TT> - -<P><TT> ACE_INET_Addr local ((u_short) 0);</TT> -<BR><TT> ACE_SOCK_Dgram client;</TT> -<BR><TT> if (client.open (local) == -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN -((LM_ERROR, "%p\n", "response open"), -1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> sprintf (buf, "I am here");</TT> -<BR><TT> if (client.send (buf, strlen (buf) -+ 1, remote) == -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN -((LM_ERROR, "%p\n", "response send"), -1);</TT> -<BR><TT> }</TT> -<BR><TT> }</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> return (0);</TT> -<BR><TT>}</TT><TT></TT> - -<P> -<HR WIDTH="100%"> - -<P>Let's move on and see what changes the clients require... - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/009/page03.html b/docs/tutorials/009/page03.html deleted file mode 100644 index b84f22bcba8..00000000000 --- a/docs/tutorials/009/page03.html +++ /dev/null @@ -1,100 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 009</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 009</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams again</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>Our new <A HREF="directed_client.cpp">directed_client.cpp</A> -is very much like our previous one. The primary difference is the -addition of a timeout to the recv() call so that we can exit somewhat gracefully -if the server doesn't like what we have to say. - -<P> -<HR WIDTH="100%"><TT></TT> - -<P><TT>#include "ace/SOCK_Dgram.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT><TT></TT> - -<P><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT><TT></TT> - -<P><TT>int main (int argc, char *argv[])</TT> -<BR><TT>{</TT> -<BR><TT> ACE_INET_Addr local ((u_short) 0);</TT> -<BR><TT> ACE_INET_Addr remote (PORT, argc > 1 ? argv[1] : "localhost");</TT> -<BR><TT> ACE_SOCK_Dgram dgram;</TT><TT></TT> - -<P><TT> if (dgram.open (local) == -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), --1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> char buf[512];</TT><TT></TT> - -<P><TT> /*</TT> -<BR><TT> In order to conform to the "protocol" -requried by the server,</TT> -<BR><TT> we allow the user to specify a signature. -A default matching</TT> -<BR><TT> the server's default is also available.</TT> -<BR><TT> */</TT> -<BR><TT> sprintf (buf, argc > 2 ? argv[2] : "Hello World!");</TT><TT></TT> - -<P><TT> if (dgram.send (buf, strlen (buf) + 1, remote) == -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), --1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> /*</TT> -<BR><TT> Because we may have sent a signature that -the server doesn't</TT> -<BR><TT> honor, we have to have some way to get -out of the recv().</TT> -<BR><TT> Most ACE objects that have potential for -infinite blocking</TT> -<BR><TT> give you the option of providing a timeout. -recv() is no</TT> -<BR><TT> exception. Here, we construct an -ACE_Time_Value representing</TT> -<BR><TT> two seconds and no micro-seconds. -If recv() fails to get</TT> -<BR><TT> a response within the two seconds, it -will return -1.</TT> -<BR><TT> */</TT> -<BR><TT> ACE_Time_Value timeout (2, 0);</TT> -<BR><TT> if (dgram.recv (buf, sizeof (buf), remote, 0, &timeout) -== -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), --1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server said (%s)\n", buf));</TT><TT></TT> - -<P><TT> return (0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> - -<P>On the next page, we see that the directed_client gets similar upgrades. - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/009/page04.html b/docs/tutorials/009/page04.html deleted file mode 100644 index 46bc80c2a2f..00000000000 --- a/docs/tutorials/009/page04.html +++ /dev/null @@ -1,74 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 009</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 009</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams again</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>As you can see in <A HREF="broadcast_client.cpp">broadcast_client.cpp</A>, -there isn't enough difference to even comment on! Look back to the -Tutorial 8 version of this file. The only difference is the addition -of the timeout variable passed to recv(). - -<P> -<HR WIDTH="100%"><TT></TT> - -<P><TT>#include "ace/SOCK_Dgram_Bcast.h"</TT> -<BR><TT>#include "ace/INET_Addr.h"</TT><TT></TT> - -<P><TT>static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</TT><TT></TT> - -<P><TT>int main (int argc, char *argv[])</TT> -<BR><TT>{</TT> -<BR><TT> ACE_INET_Addr local ((u_short) 0);</TT> -<BR><TT> ACE_INET_Addr remote (PORT, INADDR_BROADCAST);</TT> -<BR><TT> ACE_SOCK_Dgram_Bcast dgram;</TT><TT></TT> - -<P><TT> if (dgram.open (local) == -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), --1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> char buf[512];</TT><TT></TT> - -<P><TT> sprintf (buf, argc > 1 ? argv[1] : "Hello World!");</TT><TT></TT> - -<P><TT> if (dgram.send (buf, strlen (buf) + 1, remote) == -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), --1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> ACE_Time_Value timeout (2, 0);</TT> -<BR><TT> if (dgram.recv (buf, sizeof (buf), remote, 0, &timeout) -== -1)</TT> -<BR><TT> {</TT> -<BR><TT> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), --1);</TT> -<BR><TT> }</TT><TT></TT> - -<P><TT> ACE_DEBUG ((LM_DEBUG, "(%P|%t) The server at (%s) said (%s)\n",</TT> -<BR><TT> -remote.get_host_name (), buf));</TT><TT></TT> - -<P><TT> return (0);</TT> -<BR><TT>}</TT> - -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/009/page05.html b/docs/tutorials/009/page05.html deleted file mode 100644 index a48f78f8414..00000000000 --- a/docs/tutorials/009/page05.html +++ /dev/null @@ -1,50 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 009</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 009</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sending and receiving datagrams again</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<P>In this tutorial we've expanded on Tutorial 8 to provide a more discriminating -server application. The changes to the clients were trivial, amounting -to not much more than the addition of a timeout when reading a server's -potential response. The server change was a bit more since it had -to compare the clients' query with it's own signature. - -<P>In a "real" system, the signatures you swap would probably include version -information. You could even use a major/minor scheme where an exact -match isn't necessary. Another upgrade might be to have a set of -signatures at one or both ends of the conversation. The level of -service provided by the server would be determined by the signature pair -match. - -<P>Here's the final file list: -<UL> -<LI> -<A HREF="Makefile">Makefile</A></LI> - -<LI> -<A HREF="server.cpp">server.cpp</A></LI> - -<LI> -<A HREF="directed_client.cpp">directed_client.cpp</A></LI> - -<LI> -<A HREF="broadcast_client.cpp">broadcast_client.cpp</A></LI> -</UL> - -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/009/server.cpp b/docs/tutorials/009/server.cpp deleted file mode 100644 index f73c7fd4ad3..00000000000 --- a/docs/tutorials/009/server.cpp +++ /dev/null @@ -1,78 +0,0 @@ - -// $Id$ - -/* - The actual datagram operations here are exactly the same as those used in - the previous tutorial. What we've added is some logic that will prevent - this server from responding to just any old datagram. I'll limit my - comments to those pieces of code. - */ - -#include "ace/SOCK_Dgram.h" -#include "ace/INET_Addr.h" - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* - In order to be more selective, our server will be started with a - "signature". If none is given, we'll use the one here instead. - */ -static const char *default_signature = "Hello World!"; - -int main (int argc, char *argv[]) -{ - ACE_INET_Addr local (PORT); - ACE_SOCK_Dgram dgram; - - if (dgram.open (local) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - char buf[512]; - ACE_INET_Addr remote; - - while (dgram.recv (buf, sizeof (buf), remote) != -1) - { - /* - What did the client say? - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Received (%s) from (%s)\n", buf, remote.get_host_name ())); - - /* - Use a simple string-op to decide if the client is one of our own. Of - course, you could have sent numeric values or even a struct of data. For - this simple exercise, however, strings are just fine. - */ - if (ACE_OS::strcmp (buf, argc > 1 ? argv[1] : default_signature)) - { - /* - If the client didn't say something we like then log it and move on. - */ - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) Client query does not match our signature (%s). Response not sent.\n", - argc > 1 ? argv[1] : default_signature)); - } - else - { - /* - As before, we respond to the client's query. - */ - - ACE_INET_Addr local ((u_short) 0); - ACE_SOCK_Dgram client; - if (client.open (local) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "response open"), -1); - } - - sprintf (buf, "I am here"); - if (client.send (buf, strlen (buf) + 1, remote) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "response send"), -1); - } - } - } - - return (0); -} diff --git a/docs/tutorials/010/010.dsp b/docs/tutorials/010/010.dsp deleted file mode 100644 index 85a15e7585a..00000000000 --- a/docs/tutorials/010/010.dsp +++ /dev/null @@ -1,112 +0,0 @@ -# Microsoft Developer Studio Project File - Name="010" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=010 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "010.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "010.mak" CFG="010 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "010 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "010 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "010 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "010 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"message_queue.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "010 - Win32 Release"
-# Name "010 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\message_queue.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\block.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/010/Makefile b/docs/tutorials/010/Makefile deleted file mode 100644 index d52722d4994..00000000000 --- a/docs/tutorials/010/Makefile +++ /dev/null @@ -1,59 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = message_queue - -FILES = -FILES += task - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix .cpp,$(FILES)) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/010/block.h b/docs/tutorials/010/block.h deleted file mode 100644 index 583886872cb..00000000000 --- a/docs/tutorials/010/block.h +++ /dev/null @@ -1,56 +0,0 @@ - -// $Id$ - -#ifndef BLOCK_H -#define BLOCK_H - -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - This simple ACE_Message_Block derivative will inform us of it's construction - and destruction. We'll use this to assure ourselves that we don't have any - memory leaks. In a real application, of course, this isn't necessary. - */ -class Block : public ACE_Message_Block -{ -public: - Block (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block ctor 0x%x\n", (void *) this)); - } - - Block (size_t size) - : ACE_Message_Block (size) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block ctor 0x%x\n", (void *) this)); - } - - virtual ~ Block (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block dtor 0x%x\n", (void *) this)); - } -}; - -#endif - - - - - - - - - - - - - - - - - - diff --git a/docs/tutorials/010/message_queue.cpp b/docs/tutorials/010/message_queue.cpp deleted file mode 100644 index 98a9019024c..00000000000 --- a/docs/tutorials/010/message_queue.cpp +++ /dev/null @@ -1,93 +0,0 @@ - -// $Id$ - -/* - To illustrate the ACE_Message_Queue, we use a derivative of ACE_Task<>. We - also derive from ACE_Message_Block to show that we don't have memory leaks. - */ -#include "task.h" -#include "block.h" - -int run_test( int iterations, int threads ) -{ - /* - Create and open an instance of our Task object. I've overridden the - open() method to make it look more like other ACE objects. - */ - Task task; - - if (task.open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - /* - Give the threads a moment to open. This isn't really necessary but if we - don't we find that all of our blocks are constructed and enqueued before - any of the threads get created. Basically, the sleep() makes the output - look more interesting. - */ - ACE_OS::sleep (ACE_Time_Value (1)); - - int i; - for (i = 0; i < iterations; ++i) - { - /* - Create a new message block to hold our data. Here, we ask for a block - that has 128 bytes of data space. - */ - Block *message = new Block (128); - - /* - Grab the "write pointer". This is a pointer into the data area where we - can write our data. After writting the data you have to increment the - wr_ptr() so that subsequent writes won't clobber what you've put there. - */ - ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i); - message->wr_ptr (strlen (message->rd_ptr ())); - - /* - Put the message block into the queue. One of the threads in the Task - object will pick up the block and "do work" on it. - */ - if (task.putq (message) == -1) - { - break; - } - } - - /* - Once we're done, we have to signal the Task objects to shut down. There - are several choices including: - Send a message of zero length - Send a - message with a special content I don't like these choices because they're - likely to interfere with application logic. Instead, I use the message - type feature to send a message of type "hangup". The default type is - MB_DATA, so when the tasks get a MB_HANGUP type, they know to go away. - */ - Block *message = new Block (); - message->msg_type (ACE_Message_Block::MB_HANGUP); - task.putq (message); - - /* - Wait for the threads in our task object to go away. - */ - task.wait (); - - return(0); -} - -int main (int argc, char *argv[]) -{ - /* - Set the number of iterations through our putq() loop and the number of - threads to use in our Task<> derivative. - */ - int iterations = argc > 1 ? atoi (argv[1]) : 9; - int threads = argc > 2 ? atoi (argv[2]) : 2; - - (void)run_test(iterations,threads); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n")); - - return(0); -} diff --git a/docs/tutorials/010/page01.html b/docs/tutorials/010/page01.html deleted file mode 100644 index 144f7454fea..00000000000 --- a/docs/tutorials/010/page01.html +++ /dev/null @@ -1,36 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 010</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 010</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing chunks of data through an ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -In an earlier tutorial we briefly introduced ACE_Message_Queue. In this -tutorial we'll go into a bit more detail. -<P> -ACE_Message_Queue is modeled after Unix System V IPC mechanisms. The basic -idea is that you put a block of data into one end of the Queue and take it -out of the other end. Your basic FIFO in other words. The SysV mechanism -works great for passing these blocks of data between processes on the same -host but it's a bit overkill for moving blocks between threads. You could -use a pipe, socket or similar mechanism but that still has more overhead than -we really want just for moving data between threads. Process-global memory -is a good technique but then you need a way to signal the "listening" threads. -The ACE_Message_Queue is a better approach: Create blocks of data and enqueue -them in one thread while another thread (or threads) dequeue and perform work. -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/010/page02.html b/docs/tutorials/010/page02.html deleted file mode 100644 index 91ce0792147..00000000000 --- a/docs/tutorials/010/page02.html +++ /dev/null @@ -1,132 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 010</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 010</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing chunks of data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -We'll look first at <A HREF="message_queue.cpp">main()</A>. -<P> - -<HR WIDTH="100%"> -<PRE> -/* - To illustrate the ACE_Message_Queue, we use a derivative of ACE_Task<>. We - also derive from ACE_Message_Block to show that we don't have memory leaks. - */ -#include "task.h" -#include "block.h" - -int run_test( int iterations, int threads ) -{ - /* - Create and open an instance of our Task object. I've overridden the - open() method to make it look more like other ACE objects. - */ - Task task; - - if (task.open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - /* - Give the threads a moment to open. This isn't really necessary but if we - don't we find that all of our blocks are constructed and enqueued before - any of the threads get created. Basically, the sleep() makes the output - look more interesting. - */ - ACE_OS::sleep (ACE_Time_Value (1)); - - int i; - for (i = 0; i < iterations; ++i) - { - /* - Create a new message block to hold our data. Here, we ask for a block - that has 128 bytes of data space. - */ - Block *message = new Block (128); - - /* - Grab the "write pointer". This is a pointer into the data area where we - can write our data. After writting the data you have to increment the - wr_ptr() so that subsequent writes won't clobber what you've put there. - */ - ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i); - message->wr_ptr (strlen (message->rd_ptr ())); - - /* - Put the message block into the queue. One of the threads in the Task - object will pick up the block and "do work" on it. - */ - if (task.putq (message) == -1) - { - break; - } - } - - /* - Once we're done, we have to signal the Task objects to shut down. There - are several choices including: - Send a message of zero length - Send a - message with a special content I don't like these choices because they're - likely to interfere with application logic. Instead, I use the message - type feature to send a message of type "hangup". The default type is - MB_DATA, so when the tasks get a MB_HANGUP type, they know to go away. - */ - Block *message = new Block (); - message->msg_type (ACE_Message_Block::MB_HANGUP); - task.putq (message); - - /* - Wait for the threads in our task object to go away. - */ - task.wait (); - - return(0); -} - -int main (int argc, char *argv[]) -{ - /* - Set the number of iterations through our putq() loop and the number of - threads to use in our Task<> derivative. - */ - int iterations = argc > 1 ? atoi (argv[1]) : 9; - int threads = argc > 2 ? atoi (argv[2]) : 2; - - (void)run_test(iterations,threads); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n")); - - exit(0); -} -</PRE> -<HR WIDTH="100%"> -<P> -This looks a lot like our thread-pool server and it even does some things -better. In particular, I've scoped the Task object so that it's destructor -will have a chance to get called before the application exits. -Notice how we write actual data into the message block though. In the thread-pool -server we just provided a pointer. Writting the data is actually a more correct -way of doing things since you don't get into strange pointer casting situations. -What if you want to put complex objects into the message block though? We'll do -that in the next tutorial, let's stick with the basics first. -<P> -On the next page we'll take a look at our Block object... -<P> -<HR WIDTH="100%"> - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/010/page03.html b/docs/tutorials/010/page03.html deleted file mode 100644 index 566c1eb5b21..00000000000 --- a/docs/tutorials/010/page03.html +++ /dev/null @@ -1,65 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 010</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 010</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing chunks of data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -Our <A HREF="block.h">Block</A> object is a very simple derivative -of the ACE_Message_Block. The only reason I created it was to prove -that the message blocks to, indeed, get freed when we're done with 'em. -<P> - -<HR WIDTH="100%"> -<PRE> - -#include "ace/Message_Block.h" - -/* - This simple ACE_Message_Block derivative will inform us of it's construction - and destruction. We'll use this to assure ourselves that we don't have any - memory leaks. In a real application, of course, this isn't necessary. - */ -class Block : public ACE_Message_Block -{ -public: - Block (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block ctor 0x%x\n", (void *) this)); - } - - Block (size_t size) - : ACE_Message_Block (size) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block ctor 0x%x\n", (void *) this)); - } - - virtual ~ Block (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block dtor 0x%x\n", (void *) this)); - } -}; - -</PRE> -<HR WIDTH="100%"> -<P> -Ok, nothing really magic there. Some folks just feel a little uncomfortable -not doing an explicit <i>delete</i> on objects they've <i>new</i>'d so I -wanted to show you that the memory really does get cleaned up. -<P> -<HR WIDTH="100%"> - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/010/page04.html b/docs/tutorials/010/page04.html deleted file mode 100644 index c0602095cba..00000000000 --- a/docs/tutorials/010/page04.html +++ /dev/null @@ -1,84 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 010</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 010</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing chunks of data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -Our <A HREF="task.h">Task</A> object executes in one or more threads -and reads from the message queue it contains. -<P> - -<HR WIDTH="100%"> -<PRE> - -#include "ace/Task.h" - -/* - Like the thread-pool server tutorial, we'll derive from ACE_Task<>. - Our goal here is to show off the ACE_Message_Queue and the best way - to do that is to use one to pass data between threads. The easiest - way to create threads is with ACE_Task<> - */ -class Task : public ACE_Task < ACE_MT_SYNCH > -{ -public: - - typedef ACE_Task < ACE_MT_SYNCH > inherited; - - /* - The constructor/destructor are simple but take care of some - necessary housekeeping. - */ - Task (void); - ~Task (void); - - /* - To make our Task<> derivative look more like other ACE objects - I've added an open() method. It will take care of activate()ing - the object. - */ - int open (int threads = 1); - - /* - Our worker method - */ - int svc (void); - - /* - All we'll do here is print a message to the user. - */ - int close (u_long flags = 0); - -protected: - /* - Just to be clever, I'll use an ACE_Barrier to cause the threads - to sync in svc() before doing any real work. - */ - ACE_Barrier *barrier_; -}; -</PRE> -<HR WIDTH="100%"> -<P> -The only thing here that we didn't see in the thread-pool server is the -ACE_Barrier. The application logic really doesn't need it but it is a -handy way to synchronize the threads at the beginning of svc(). In testing -I found that if I didn't sync svc(), the first thread to get activated would -tend to get all of the messages before the other threads came alive. -<P> -<HR WIDTH="100%"> - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/010/page05.html b/docs/tutorials/010/page05.html deleted file mode 100644 index afcb23f1f1a..00000000000 --- a/docs/tutorials/010/page05.html +++ /dev/null @@ -1,168 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 010</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 010</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing chunks of data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -Our <A HREF="task.cpp">Task</A> object definition: -<P> - -<HR WIDTH="100%"> -<PRE> - -#include "task.h" -#include "block.h" - -/* - Set our housekeeping pointer to NULL and tell the user we exist. - */ -Task::Task (void) -: barrier_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task ctor 0x%x\n", (void *) this)); -} - -/* - Take care of cleanup & tell the user we're going away. -*/ -Task::~Task (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task dtor 0x%x\n", (void *) this)); - - /* - Get our shutdown notification out of the queue and release it. - */ - ACE_Message_Block * message; - this->getq(message); - message->release(); - - delete barrier_; -} - -/* - Open the object to do work. We create the Barrier object and tell - it how many threads we'll be using. Next, we activate the Task - into the number of requested threads. -*/ -int Task::open (int threads) -{ - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} - -/* - Tell the user we're closing and invoke the baseclass' close() to - take care of things. -*/ -int Task::close (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task close 0x%x\n", (void *) this)); - return inherited::close (flags); -} - -/* - Our svc() method waits for work on the queue and then processes that work. - */ -int Task::svc (void) -{ - /* - This will cause all of the threads to wait on this line until all - have invoked this method. The net result is that no thread in the - Task will get a shot at the queue until all of the threads are active. - There's no real need to do this but it's an easy intro into the use - of ACE_Barrier. - */ - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %d\n", (void *) this, ACE_Thread::self ())); - - /* - Remember that get() needs a reference to a pointer. To save stack - thrashing we'll go ahead and create a pointer outside of the almost- - infinite loop. - */ - ACE_Message_Block *message; - while (1) - { - /* - Get a message from the queue. - */ - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); - } - - /* - If we got the shutdown request, we need to go away. - */ - if (message->msg_type () == ACE_Message_Block::MB_HANGUP) - { - /* - Forward the request to any peer threads. - */ - this->putq (message); - - /* - Leave the infinite loop so that the thread exits. - */ - break; - } - - /* - The message queue stores char* data. We use rd_ptr() to get to - the beginning of the data. - */ - const char *cp = message->rd_ptr (); - - /* - Move the rd_ptr() past the data we read. This isn't real useful - here since we won't be reading any more from the block but it's - a good habit to get into. - */ - message->rd_ptr( strlen(cp) ); - - /* - Display the block's address and data to the user. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block 0x%x contains (%s)\n", (void *) message, cp)); - - /* - Pretend that it takes a while to process the data. - */ - ACE_OS::sleep (ACE_Time_Value (0, 5000)); - - /* - Release the message block. Notice that we never delete a message block. - Blocks are reference counted & the release() method will take care of - the delete when there are no more references to the data. - */ - message->release (); - } - - return (0); -} -</PRE> -<HR WIDTH="100%"> -<P> -This is all pretty straight-forward too. One gottcha we avoided was a memory leak -due to our shutdown message. Notice that svc() enqueues that block without bothering -to see if there are any more threads to dequeue it. Thats why our dtor can call getq() -without worrying about blocking infinitely: it knows the message block will be there. -<P> -<HR WIDTH="100%"> - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/010/page06.html b/docs/tutorials/010/page06.html deleted file mode 100644 index 657e05b9d4c..00000000000 --- a/docs/tutorials/010/page06.html +++ /dev/null @@ -1,64 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 010</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 010</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing chunks of data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -Since I added Block just to give us output, let's take a look at that output. - -<P> -<HR WIDTH="100%"> -<PRE> -[jcej@chiroptera 010]$./message_queue 4 2 -(8910|1024) Task ctor 0xbffff9c4 -(8910|2050) Task 0xbffff9c4 starts in thread 2050 -(8910|1025) Task 0xbffff9c4 starts in thread 1025 -(8910|1024) Block ctor 0x8052398 -(8910|1024) Block ctor 0x8052488 -(8910|1024) Block ctor 0x8052578 -(8910|1024) Block ctor 0x8052668 -(8910|1024) Block ctor 0x8052758 -(8910|1025) Block 0x8052398 contains (This is message 0.) -(8910|2050) Block 0x8052488 contains (This is message 1.) -(8910|1025) Block dtor 0x8052398 -(8910|1025) Block 0x8052578 contains (This is message 2.) -(8910|2050) Block dtor 0x8052488 -(8910|2050) Block 0x8052668 contains (This is message 3.) -(8910|1025) Block dtor 0x8052578 -(8910|1025) Task close 0xbffff9c4 -(8910|2050) Block dtor 0x8052668 -(8910|2050) Task close 0xbffff9c4 -(8910|1024) Task dtor 0xbffff9c4 -(8910|1024) Block dtor 0x8052758 -(8910|1024) Application exiting -[jcej@chiroptera 010]$ -</PRE> -<HR WIDTH="100%"> -<P> -Notice that each <i>Block ctor</i> has a corresponding <i>Block dtor</i>. -We've proven the point that all memory gets cleaned up. We also see that -both threads get to do some work and that both close as expected. -<P> -It's also worth mentioning that it's just an accident that all of the blocks -are created and enqueued before any are processed. Run the test on a multi-processor -or with more iterations and you'll see some get processed before all are created. -<P> -<HR WIDTH="100%"> - - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>][<A HREF="page07.html">Continue -This Tutorial</A>]</CENTER> -</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/010/page07.html b/docs/tutorials/010/page07.html deleted file mode 100644 index 4df9c0e155e..00000000000 --- a/docs/tutorials/010/page07.html +++ /dev/null @@ -1,36 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 010</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 010</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing chunks of data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -That's it for Tutorial 10. There are some esoteric changes between the thread-pool server -and this application but it's basically the same. In the next tutorial I'll modify this just -a bit to move non-trivial data through the queue. -<P> - -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="block.h">block.h</A> -<LI><A HREF="message_queue.cpp">message_queue.cpp</A> -<LI><A HREF="task.cpp">task.cpp</A> -<LI><A HREF="task.h">task.h</A> -</UL> -<HR WIDTH="100%"> - - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> - diff --git a/docs/tutorials/010/task.cpp b/docs/tutorials/010/task.cpp deleted file mode 100644 index 84f70cae0ee..00000000000 --- a/docs/tutorials/010/task.cpp +++ /dev/null @@ -1,134 +0,0 @@ - -// $Id$ - -#include "task.h" -#include "block.h" - -/* - Set our housekeeping pointer to NULL and tell the user we exist. - */ -Task::Task (void) -: barrier_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task ctor 0x%x\n", (void *) this)); -} - -/* - Take care of cleanup & tell the user we're going away. -*/ -Task::~Task (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task dtor 0x%x\n", (void *) this)); - - /* - Get our shutdown notification out of the queue and release it. - */ - ACE_Message_Block * message; - this->getq(message); - message->release(); - - delete barrier_; -} - -/* - Open the object to do work. We create the Barrier object and tell - it how many threads we'll be using. Next, we activate the Task - into the number of requested threads. -*/ -int Task::open (int threads) -{ - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} - -/* - Tell the user we're closing and invoke the baseclass' close() to - take care of things. -*/ -int Task::close (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task close 0x%x\n", (void *) this)); - return inherited::close (flags); -} - -/* - Our svc() method waits for work on the queue and then processes that work. - */ -int Task::svc (void) -{ - /* - This will cause all of the threads to wait on this line until all - have invoked this method. The net result is that no thread in the - Task will get a shot at the queue until all of the threads are active. - There's no real need to do this but it's an easy intro into the use - of ACE_Barrier. - */ - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %d\n", (void *) this, ACE_Thread::self ())); - - /* - Remember that get() needs a reference to a pointer. To save stack - thrashing we'll go ahead and create a pointer outside of the almost- - infinite loop. - */ - ACE_Message_Block *message; - while (1) - { - /* - Get a message from the queue. - */ - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); - } - - /* - If we got the shutdown request, we need to go away. - */ - if (message->msg_type () == ACE_Message_Block::MB_HANGUP) - { - /* - Forward the request to any peer threads. - */ - this->putq (message); - - /* - Leave the infinite loop so that the thread exits. - */ - break; - } - - /* - The message queue stores char* data. We use rd_ptr() to get to - the beginning of the data. - */ - const char *cp = message->rd_ptr (); - - /* - Move the rd_ptr() past the data we read. This isn't real useful - here since we won't be reading any more from the block but it's - a good habit to get into. - */ - message->rd_ptr( strlen(cp) ); - - /* - Display the block's address and data to the user. - */ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block 0x%x contains (%s)\n", (void *) message, cp)); - - /* - Pretend that it takes a while to process the data. - */ - ACE_OS::sleep (ACE_Time_Value (0, 5000)); - - /* - Release the message block. Notice that we never delete a message block. - Blocks are reference counted & the release() method will take care of - the delete when there are no more references to the data. - */ - message->release (); - } - - return (0); -} diff --git a/docs/tutorials/010/task.h b/docs/tutorials/010/task.h deleted file mode 100644 index 2aecb429c03..00000000000 --- a/docs/tutorials/010/task.h +++ /dev/null @@ -1,57 +0,0 @@ - -// $Id$ - -#ifndef TASK_H -#define TASK_H - -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - Like the thread-pool server tutorial, we'll derive from ACE_Task<>. - Our goal here is to show off the ACE_Message_Queue and the best way - to do that is to use one to pass data between threads. The easiest - way to create threads is with ACE_Task<> - */ -class Task : public ACE_Task < ACE_MT_SYNCH > -{ -public: - - typedef ACE_Task < ACE_MT_SYNCH > inherited; - - /* - The constructor/destructor are simple but take care of some - necessary housekeeping. - */ - Task (void); - ~Task (void); - - /* - To make our Task<> derivative look more like other ACE objects - I've added an open() method. It will take care of activate()ing - the object. - */ - int open (int threads = 1); - - /* - Our worker method - */ - int svc (void); - - /* - All we'll do here is print a message to the user. - */ - int close (u_long flags = 0); - -protected: - /* - Just to be clever, I'll use an ACE_Barrier to cause the threads - to sync in svc() before doing any real work. - */ - ACE_Barrier *barrier_; -}; - -#endif diff --git a/docs/tutorials/011/011.dsp b/docs/tutorials/011/011.dsp deleted file mode 100644 index 0118e99d156..00000000000 --- a/docs/tutorials/011/011.dsp +++ /dev/null @@ -1,116 +0,0 @@ -# Microsoft Developer Studio Project File - Name="011" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=011 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "011.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "011.mak" CFG="011 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "011 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "011 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "011 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "011 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"message_queue.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "011 - Win32 Release"
-# Name "011 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\message_queue.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\block.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\data.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/011/Makefile b/docs/tutorials/011/Makefile deleted file mode 100644 index d52722d4994..00000000000 --- a/docs/tutorials/011/Makefile +++ /dev/null @@ -1,59 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = message_queue - -FILES = -FILES += task - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix .cpp,$(FILES)) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/011/block.h b/docs/tutorials/011/block.h deleted file mode 100644 index 1ffc5cb4e9d..00000000000 --- a/docs/tutorials/011/block.h +++ /dev/null @@ -1,33 +0,0 @@ - -// $Id$ - -#ifndef BLOCK_H -#define BLOCK_H - -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class Block : public ACE_Message_Block -{ -public: - Block (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block ctor 0x%x\n", (void *) this)); - } - - Block (size_t size) - : ACE_Message_Block (size) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block ctor 0x%x\n", (void *) this)); - } - - virtual ~ Block (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block dtor 0x%x\n", (void *) this)); - } -}; - -#endif diff --git a/docs/tutorials/011/data.h b/docs/tutorials/011/data.h deleted file mode 100644 index 998b4d009ec..00000000000 --- a/docs/tutorials/011/data.h +++ /dev/null @@ -1,60 +0,0 @@ - -// $Id$ - -#ifndef DATA_H -#define DATA_H - -class DataBase -{ -public: - DataBase (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) DataBase ctor 0x%x\n", (void *) this)); - } - virtual ~ DataBase (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) DataBase dtor 0x%x\n", (void *) this)); - } - - void who_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) DataBase instance 0x%x\n", (void *) this)); - } - - virtual void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a DataBase object\n")); - } - -}; - -class Data : public DataBase -{ -public: - Data (void) - : message_ (-1) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data ctor 0x%x\n", (void *) this)); - } - - Data (int message) - : message_ (message) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data ctor 0x%x for message %d\n", (void *) this, message_)); - } - virtual ~ Data (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data dtor 0x%x\n", (void *) this)); - } - - void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Data object for message %d\n", message_)); - } - -protected: - int message_; - -}; - -#endif diff --git a/docs/tutorials/011/message_queue.cpp b/docs/tutorials/011/message_queue.cpp deleted file mode 100644 index 8bd1e0cc13a..00000000000 --- a/docs/tutorials/011/message_queue.cpp +++ /dev/null @@ -1,79 +0,0 @@ - -// $Id$ - -/* - Most of this is the same as the previous tutorial, so I'll just point out - the differences. - */ -#include "task.h" -#include "block.h" -#include "data.h" - -int run_test (int iterations, int threads) -{ - Task task; - - if (task.open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - -ACE_OS::sleep (ACE_Time_Value (1)); - - int i; - for (i = 0; i < iterations; ++i) - { - /* - Construct a Data object that we'll put into the Queue. - */ - Data data (i); - - /* - Create a block large enough for our Data object as well as a text - message. - */ - Block *message = new Block (sizeof (data) + 128); - - /* - As before, put a text message into the block. - */ - ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i); - message->wr_ptr (strlen (message->rd_ptr ())); - - *(message->wr_ptr ()) = 0; // Null-terminate the string we just wrote - - message->wr_ptr (1); // Move beyond the NULL - - /* - To copy arbitrary data into a message block, we use the copy() method. - Since it wants a 'const char*', we have to cast our Data pointer. - */ - message->copy ((const char *) &data, sizeof (data)); - message->wr_ptr (sizeof (data)); - - if (task.putq (message) == -1) - { - break; - } - } - - Block *message = new Block (); -message->msg_type (ACE_Message_Block::MB_HANGUP); - task.putq (message); - - task.wait (); - - return (0); -} - -int main (int argc, char *argv[]) -{ - int iterations = argc > 1 ? atoi (argv[1]) : 4; - int threads = argc > 2 ? atoi (argv[2]) : 2; - - (void) run_test (iterations, threads); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n")); - - return (0); -} diff --git a/docs/tutorials/011/page01.html b/docs/tutorials/011/page01.html deleted file mode 100644 index 26e764d3f84..00000000000 --- a/docs/tutorials/011/page01.html +++ /dev/null @@ -1,30 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 011</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 011</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing non-trivial data through an ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -In the previous tutorial we learned how to put text into a message queue. -While that may be useful, it isn't very exciting or realistic. In most -cases you'll need to move complex data structures between your threads. -<P> -In this tutorial I'll expand the previous by moving not only a text string -but also a more complex object. In the next tutorial I'll change things -again so that we move the complex object a bit more efficiently. -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/011/page02.html b/docs/tutorials/011/page02.html deleted file mode 100644 index 476121bcbb7..00000000000 --- a/docs/tutorials/011/page02.html +++ /dev/null @@ -1,111 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 011</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 011</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing non-trivial data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -We'll look first at <A HREF="message_queue.cpp">main()</A>. A large part of this is -the same as before, so I've only commented the changes. -<P> - -<HR WIDTH="100%"> -<P> -<PRE> -#include "task.h" -#include "block.h" -#include "data.h" - -int run_test (int iterations, int threads) -{ - Task task; - - if (task.open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - ACE_OS::sleep (ACE_Time_Value (1)); - - int i; - for (i = 0; i < iterations; ++i) - { - /* - Construct a Data object that we'll put into the Queue. - */ - Data data (i); - - /* - Create a block large enough for our Data object as well - as a text message. - */ - Block *message = new Block (sizeof (data) + 128); - - /* - As before, put a text message into the block. - */ - ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i); - message->wr_ptr (strlen (message->rd_ptr ())); - - *(message->wr_ptr()) = 0; // Null-terminate the string we just wrote - message->wr_ptr(1); // Move beyond the NULL - - /* - To copy arbitrary data into a message block, we use the copy() method. - Since it wants a 'const char*', we have to cast our Data pointer. - */ - message->copy ((const char *) &data, sizeof (data)); - message->wr_ptr (sizeof (data)); - - if (task.putq (message) == -1) - { - break; - } - } - - Block *message = new Block (); - message->msg_type (ACE_Message_Block::MB_HANGUP); - task.putq (message); - - task.wait (); - - return (0); -} - -int main (int argc, char *argv[]) -{ - int iterations = argc > 1 ? atoi (argv[1]) : 4; - int threads = argc > 2 ? atoi (argv[2]) : 2; - - (void) run_test (iterations, threads); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n")); - - exit (0); -} -</PRE> - -<HR WIDTH="100%"> -<P> -The new trick here is the use of copy() to copy our abstract data object -into the message block memory. Notice that it's OK to let the Data object -go out of scope at that point since we've got a separate copy. If you've -got something with a non-trivial ctor/dtor then this won't work. We'll address -that in the next tutorial. -<P> -<HR WIDTH="100%"> - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/011/page03.html b/docs/tutorials/011/page03.html deleted file mode 100644 index 12d121e0834..00000000000 --- a/docs/tutorials/011/page03.html +++ /dev/null @@ -1,136 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 011</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 011</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing non-trivial data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -Our <A HREF="task.cpp">Task</A> object definition. As with message_queue.cpp, -I've only commented the changes. -<P> - -<HR WIDTH="100%"> -<PRE> - -#include "task.h" -#include "block.h" -#include "data.h" - -Task::Task (void) -: barrier_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task ctor 0x%x\n", (void *) this)); -} - -Task::~Task (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task dtor 0x%x\n", (void *) this)); - - ACE_Message_Block *message; - this->getq (message); - message->release (); - - delete barrier_; -} - -int Task::open (int threads) -{ - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} -int Task::close (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task close 0x%x\n", (void *) this)); - return inherited::close (flags); -} - -int Task::svc (void) -{ - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %d\n", (void *) this, ACE_Thread::self ())); - - ACE_Message_Block *message; - while (1) - { - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); - } - - if (message->msg_type () == ACE_Message_Block::MB_HANGUP) - { - this->putq (message); - - break; - } - - const char *cp = message->rd_ptr (); - message->rd_ptr (strlen (cp) + 1); // Don't forget to skip the NULL we - // inserted - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block 0x%x contains (%s)\n", (void *) message, cp)); - - /* - Create a Data object into which we can extract the message block - contents. - */ - Data data; - /* - Use the rd_ptr() to access the message block data. Note that we've - already moved it past the text string in the block. - */ - ACE_OS::memmove ((char *) &data, message->rd_ptr (), sizeof (data)); - message->rd_ptr (sizeof (data)); // Move the rd_ptr() beyond the data. - - /* - Invoke a couple of method calls on the object we constructed. - */ - data.who_am_i (); - data.what_am_i (); - - /* - An alternate approach: - - Data * data; - data = (Data *)message->rd_ptr(); - data->who_am_i(); - data->what_am_i(); - message->rd_ptr(sizeof(Data)); - - Even though this cuts down on the number of copies & constructions, I'm - not real fond of it. You can get into trouble in a hurry by treating - memory blocks as multiple data types... - */ - - - ACE_OS::sleep (ACE_Time_Value (0, 5000)); - - message->release (); - } - - return (0); -} -</PRE> -<HR WIDTH="100%"> -<P> -Notice how we had to create a temporary Data object to copy the stuff out -of the message block? Again, if there were non-trivial ctor/dtors involved -then this wouldn't work at all. -<P> -<HR WIDTH="100%"> - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/011/page04.html b/docs/tutorials/011/page04.html deleted file mode 100644 index 9d1178d924c..00000000000 --- a/docs/tutorials/011/page04.html +++ /dev/null @@ -1,91 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 011</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 011</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing non-trivial data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -Before we go further, let's look at this <A HREF="data.h">Data</A> object -that's causing all the fuss. - -<P> -<HR WIDTH="100%"> -<PRE> - -class DataBase -{ -public: - DataBase (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) DataBase ctor 0x%x\n", (void *) this)); - } - virtual ~ DataBase (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) DataBase dtor 0x%x\n", (void *) this)); - } - - void who_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) DataBase instance 0x%x\n", (void *) this)); - } - - virtual void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a DataBase object\n")); - } - -}; - -class Data : public DataBase -{ -public: - Data (void) - : message_ (-1) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data ctor 0x%x\n", (void *) this)); - } - - Data (int message) - : message_ (message) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data ctor 0x%x for message %d\n", (void *) this, message_)); - } - virtual ~ Data (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Data dtor 0x%x\n", (void *) this)); - } - - void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Data object for message %d\n", message_)); - } - -protected: - int message_; - -}; - -</PRE> -<HR WIDTH="100%"> -<P> -Ok, no mysterious magic on this one. Just a simple object and derivative -that report their existence. -<P> -<HR WIDTH="100%"> - - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>][<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> -</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/011/page05.html b/docs/tutorials/011/page05.html deleted file mode 100644 index 921991f4bc2..00000000000 --- a/docs/tutorials/011/page05.html +++ /dev/null @@ -1,99 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 011</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 011</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing non-trivial data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> - -Let's take a look at this new program's output: - -<P> -<HR WIDTH="100%"> -<PRE> -[jcej@chiroptera 011]$./message_queue 4 2 -(12108|1024) Task ctor 0xbffff9c8 -(12108|2050) Task 0xbffff9c8 starts in thread 2050 -(12108|1025) Task 0xbffff9c8 starts in thread 1025 -(12108|1024) DataBase ctor 0xbffff9c0 -(12108|1024) Data ctor 0xbffff9c0 for message 0 -(12108|1024) Block ctor 0x8052d08 -(12108|1024) Data dtor 0xbffff9c0 -(12108|1024) DataBase dtor 0xbffff9c0 -(12108|1024) DataBase ctor 0xbffff9c0 -(12108|1024) Data ctor 0xbffff9c0 for message 1 -(12108|1024) Block ctor 0x8052e00 -(12108|1024) Data dtor 0xbffff9c0 -(12108|1024) DataBase dtor 0xbffff9c0 -(12108|1024) DataBase ctor 0xbffff9c0 -(12108|1024) Data ctor 0xbffff9c0 for message 2 -(12108|1024) Block ctor 0x8052ef8 -(12108|1024) Data dtor 0xbffff9c0 -(12108|1024) DataBase dtor 0xbffff9c0 -(12108|1024) DataBase ctor 0xbffff9c0 -(12108|1024) Data ctor 0xbffff9c0 for message 3 -(12108|1024) Block ctor 0x8052ff0 -(12108|1024) Data dtor 0xbffff9c0 -(12108|1024) DataBase dtor 0xbffff9c0 -(12108|1024) Block ctor 0x80530e8 -(12108|1025) Block 0x8052d08 contains (This is message 0.) -(12108|1025) DataBase ctor 0xbf9ffe20 -(12108|1025) Data ctor 0xbf9ffe20 -(12108|1025) DataBase instance 0xbf9ffe20 -(12108|1025) I am a Data object for message 0 -(12108|1025) Block dtor 0x8052d08 -(12108|1025) Data dtor 0xbf9ffe20 -(12108|1025) DataBase dtor 0xbf9ffe20 -(12108|1025) Block 0x8052e00 contains (This is message 1.) -(12108|1025) DataBase ctor 0xbf9ffe20 -(12108|1025) Data ctor 0xbf9ffe20 -(12108|1025) DataBase instance 0xbf9ffe20 -(12108|1025) I am a Data object for message 1 -(12108|1025) Block dtor 0x8052e00 -(12108|1025) Data dtor 0xbf9ffe20 -(12108|1025) DataBase dtor 0xbf9ffe20 -(12108|1025) Block 0x8052ef8 contains (This is message 2.) -(12108|1025) DataBase ctor 0xbf9ffe20 -(12108|1025) Data ctor 0xbf9ffe20 -(12108|1025) DataBase instance 0xbf9ffe20 -(12108|1025) I am a Data object for message 2 -(12108|1025) Block dtor 0x8052ef8 -(12108|1025) Data dtor 0xbf9ffe20 -(12108|1025) DataBase dtor 0xbf9ffe20 -(12108|1025) Block 0x8052ff0 contains (This is message 3.) -(12108|1025) DataBase ctor 0xbf9ffe20 -(12108|1025) Data ctor 0xbf9ffe20 -(12108|1025) DataBase instance 0xbf9ffe20 -(12108|1025) I am a Data object for message 3 -(12108|2050) Task close 0xbffff9c8 -(12108|1025) Block dtor 0x8052ff0 -(12108|1025) Data dtor 0xbf9ffe20 -(12108|1025) DataBase dtor 0xbf9ffe20 -(12108|1025) Task close 0xbffff9c8 -(12108|1024) Task dtor 0xbffff9c8 -(12108|1024) Block dtor 0x80530e8 -(12108|1024) Application exiting -[jcej@chiroptera 011]$ -</PRE> -<HR WIDTH="100%"> -<P> -Other than being more verbose because of the Data object, this shows us -the same thing we've seen before. -<P> -<HR WIDTH="100%"> - - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>][<A HREF="page06.html">Continue -This Tutorial</A>]</CENTER> -</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/011/page06.html b/docs/tutorials/011/page06.html deleted file mode 100644 index 306575747b6..00000000000 --- a/docs/tutorials/011/page06.html +++ /dev/null @@ -1,38 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 011</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 011</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing non-trivial data through an ACE_Message_Queue</FONT></B></CENTER> - - -<HR WIDTH="100%"> -<P> -So, this time we stuffed an object into the message queue instead of just text -data. Each time required two object constructions (and subsequent destructions) -and two "deep" copy operations on the object. There might actually be times when -this is OK for your application but I prefer to keep those things down to a -minimum. In the next tutorial I'll show you a way to do that. -<P> - -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="block.h">block.h</A> -<LI><A HREF="data.h">data.h</A> -<LI><A HREF="message_queue.cpp">message_queue.cpp</A> -<LI><A HREF="task.cpp">task.cpp</A> -<LI><A HREF="task.h">task.h</A> -</UL> -<HR WIDTH="100%"> - - -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> - diff --git a/docs/tutorials/011/task.cpp b/docs/tutorials/011/task.cpp deleted file mode 100644 index a7215191481..00000000000 --- a/docs/tutorials/011/task.cpp +++ /dev/null @@ -1,102 +0,0 @@ - -// $Id$ - -#include "task.h" -#include "block.h" -#include "data.h" - -Task::Task (void) -: barrier_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task ctor 0x%x\n", (void *) this)); -} - -Task::~Task (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task dtor 0x%x\n", (void *) this)); - - ACE_Message_Block *message; - this->getq (message); - message->release (); - - delete barrier_; -} - -int Task::open (int threads) -{ - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} -int Task::close (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task close 0x%x\n", (void *) this)); - return inherited::close (flags); -} - -int Task::svc (void) -{ - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %d\n", (void *) this, ACE_Thread::self ())); - - ACE_Message_Block *message; - while (1) - { - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); - } - - if (message->msg_type () == ACE_Message_Block::MB_HANGUP) - { - this->putq (message); - - break; - } - - const char *cp = message->rd_ptr (); - message->rd_ptr (strlen (cp) + 1); // Don't forget to skip the NULL we - // inserted - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block 0x%x contains (%s)\n", (void *) message, cp)); - - /* - Create a Data object into which we can extract the message block - contents. - */ - Data data; - /* - Use the rd_ptr() to access the message block data. Note that we've - already moved it past the text string in the block. - */ - ACE_OS::memmove ((char *) &data, message->rd_ptr (), sizeof (data)); - message->rd_ptr (sizeof (data)); // Move the rd_ptr() beyond the data. - - /* - Invoke a couple of method calls on the object we constructed. - */ - data.who_am_i (); - data.what_am_i (); - - /* - An alternate approach: - - Data * data; - data = (Data *)message->rd_ptr(); - data->who_am_i(); - data->what_am_i(); - message->rd_ptr(sizeof(Data)); - - Even though this cuts down on the number of copies & constructions, I'm - not real fond of it. You can get into trouble in a hurry by treating - memory blocks as multiple data types... - */ - - - ACE_OS::sleep (ACE_Time_Value (0, 5000)); - - message->release (); - } - - return (0); -} diff --git a/docs/tutorials/011/task.h b/docs/tutorials/011/task.h deleted file mode 100644 index 8646fac1a7c..00000000000 --- a/docs/tutorials/011/task.h +++ /dev/null @@ -1,32 +0,0 @@ - -// $Id$ - -#ifndef TASK_H -#define TASK_H - -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -class Task : public ACE_Task < ACE_MT_SYNCH > -{ -public: - - typedef ACE_Task < ACE_MT_SYNCH > inherited; - - Task (void); - ~Task (void); - - int open (int threads = 1); - - int svc (void); - - int close (u_long flags = 0); - -protected: - ACE_Barrier * barrier_; -}; - -#endif diff --git a/docs/tutorials/012/012.dsp b/docs/tutorials/012/012.dsp deleted file mode 100644 index 3e3fbb7c250..00000000000 --- a/docs/tutorials/012/012.dsp +++ /dev/null @@ -1,112 +0,0 @@ -# Microsoft Developer Studio Project File - Name="012" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=012 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "012.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "012.mak" CFG="012 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "012 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "012 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "012 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "012 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"message_queue.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "012 - Win32 Release"
-# Name "012 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\message_queue.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\data.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/012/Makefile b/docs/tutorials/012/Makefile deleted file mode 100644 index d52722d4994..00000000000 --- a/docs/tutorials/012/Makefile +++ /dev/null @@ -1,59 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = message_queue - -FILES = -FILES += task - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix .cpp,$(FILES)) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/012/data.h b/docs/tutorials/012/data.h deleted file mode 100644 index 54e8e55e87c..00000000000 --- a/docs/tutorials/012/data.h +++ /dev/null @@ -1,132 +0,0 @@ - -// $Id$ - -#ifndef DATA_H -#define DATA_H - -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - We'll start by defining a basic unit of work that can be put into - the message queue. The threads in the pool will expect to find one - of these in each message block and will invoke a method or two. -*/ -class Unit_Of_Work -{ -public: - Unit_Of_Work (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work ctor 0x%x\n", (void *) this)); - } - virtual ~ Unit_Of_Work (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work dtor 0x%x\n", (void *) this)); - } - - void who_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work instance 0x%x\n", (void *) this)); - } - - virtual void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Unit_Of_Work object\n")); - } - -}; - -/* - Now, we specialize the Unit_Of_Work object to do something - different. By overriding the virtual methods, we can do whatever - "real work" is needed but the thread pool doesn't have to know the specifics. -*/ -class Work : public Unit_Of_Work -{ -public: - Work (void) - : message_ (-1) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work ctor 0x%x\n", (void *) this)); - } - - Work (int message) - : message_ (message) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work ctor 0x%x for message %d\n", (void *) this, message_)); - } - virtual ~ Work (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work dtor 0x%x\n", (void *) this)); - } - - void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Work object for message %d\n", message_)); - } - -protected: - int message_; - -}; - -/* - We derive a Message_Block from ACE_Message_Block and teach it about - our Unit_Of_Work object. When our task's svc() method pulls a block - out of the queue, it can then invoke the virtual methods of the work - object safely. In this implementation we've also retained the - original ACE_Message_Block functionallity so that we can use the - underlying ACE_Data_Block objects to store data other than our - Unit_Of_Work. -*/ -class Message_Block : public ACE_Message_Block -{ -public: - typedef ACE_Message_Block inherited; - - /* - Construct our underlying ACE_Message_Block with the requested - data size and initialize our Unit_Of_Work pointer with the - given object instance. Note that this Message_Block instance - now assumes ownership of the Unit_Of_Work and will delete it - when the Message_Block is deleted. - */ - Message_Block( size_t size, Unit_Of_Work * _data ) - : inherited(size), data_(_data) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Message_Block ctor 0x%x for 0x%x\n", (void *) this, data_)); - } - - ~Message_Block(void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Message_Block dtor 0x%x for 0x%x\n", (void *) this, data_)); - delete data_; - } - - /* - Return the Unit_Of_Work so that the task can invoke methods on - it. - */ - Unit_Of_Work * data(void) - { - return this->data_; - } - -protected: - Unit_Of_Work * data_; - - /* - Disallow these very dangerous operations. - If we were to copy a Message_Block object then the data_ - pointer would get copied and we would eventually end up - deleting the same object multiple times! That's not good. By - preventing the copy, we can avoid this. - */ - Message_Block &operator= (const Message_Block &); - Message_Block (const Message_Block &); -}; - -#endif diff --git a/docs/tutorials/012/message_queue.cpp b/docs/tutorials/012/message_queue.cpp deleted file mode 100644 index 140931ba1de..00000000000 --- a/docs/tutorials/012/message_queue.cpp +++ /dev/null @@ -1,96 +0,0 @@ - -// $Id$ - -#include "data.h" -#include "task.h" - -/* - I want to be sure that our Task object gets destructed correctly, so - I'll do most of the application 'work' in run_test() instead of - main() -*/ -int run_test (int iterations, int threads) -{ - /* - Create the Task which is our thread pool for doing work - */ - Task task; - - if (task.open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - /* - Give the Task a chance to enter it's svc() method. This isn't - really necessary and you probably wouldn't do it in a real - application but it makes the output more interesting. - */ - ACE_OS::sleep (ACE_Time_Value (1)); - - for (int i = 0; i < iterations; ++i) - { - /* - Construct a Work object that we'll put into the Queue. Give it - the iteration number so that it can identify itself in the output. - */ - Work * data = new Work(i); - - /* - Create a block that contains our Work object but also has - enough room for a text message. - */ - Message_Block *message = new Message_Block (128, data); - - /* - As before, put a text message into the block. - */ - ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i); - message->wr_ptr (strlen (message->rd_ptr ())+1); - - /* - Add the work to our thread pool - */ - if (task.putq (message) == -1) - { - break; - } - } - - /* - Insert a HANGUP message block to tell the thread pool to shut - itself down. - */ - Message_Block *message = new Message_Block (0,0); - message->msg_type (ACE_Message_Block::MB_HANGUP); - task.putq (message); - - /* - Wait for the all threads of the Task to exit. It is rather rude - to let the Task go out of scope without doing this first. - */ - task.wait (); - - return (0); -} - -int main (int argc, char *argv[]) -{ - /* - Give the user a chance to override the default number of - iterations and pool threads. - */ - int iterations = argc > 1 ? atoi (argv[1]) : 4; - int threads = argc > 2 ? atoi (argv[2]) : 2; - - /* - Use the function above to do the actual test. As I said, this - lets us see the Task go out of scope and destruct before our - "exiting" message below. - */ - (void) run_test (iterations, threads); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n")); - - return (0); -} diff --git a/docs/tutorials/012/page01.html b/docs/tutorials/012/page01.html deleted file mode 100644 index 21b540cece4..00000000000 --- a/docs/tutorials/012/page01.html +++ /dev/null @@ -1,32 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 012</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 012</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing classes through ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -Last time around we put an object into a message queue by using the -copy() method to create a duplicate of the object. That's probably OK -for simple objects that aren't very large. However, if you have an -object that contains pointers or tons of data then that approach is -going to cause problems. -<P> -What we'll do in this tutorial is specialize the ACE_Message_Block -object so that it can carry our data more efficiently. As you'll see, -this isn't very difficult at all. -<P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/012/page02.html b/docs/tutorials/012/page02.html deleted file mode 100644 index cfe4eb8df3b..00000000000 --- a/docs/tutorials/012/page02.html +++ /dev/null @@ -1,104 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 012</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 012</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing classes through ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -We normally start by looking at main() and work our way out from -there. This time, I want to start by showing you the ACE_Message_Block -derivative but before that, I have to introduce you to the Work object -and it's baseclass Unit_Of_Work -<P> -<HR WIDTH="100%"> -<PRE> - -/* - We'll start by defining a basic unit of work that can be put into - the message queue. The threads in the pool will expect to find one - of these in each message block and will invoke a method or two. -*/ -class Unit_Of_Work -{ -public: - Unit_Of_Work (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work ctor 0x%x\n", (void *) this)); - } - virtual ~ Unit_Of_Work (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work dtor 0x%x\n", (void *) this)); - } - - void who_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work instance 0x%x\n", (void *) this)); - } - - virtual void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Unit_Of_Work object\n")); - } - -}; - -/* - Now, we specialize the Unit_Of_Work object to do something - different. By overriding the virtual method, we can do whatever - "real work" is needed but the thread pool doesn't have to know the specifics. -*/ -class Work : public Unit_Of_Work -{ -public: - Work (void) - : message_ (-1) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work ctor 0x%x\n", (void *) this)); - } - - Work (int message) - : message_ (message) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work ctor 0x%x for message %d\n", (void *) this, message_)); - } - virtual ~ Work (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work dtor 0x%x\n", (void *) this)); - } - - void what_am_i (void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Work object for message %d\n", message_)); - } - -protected: - int message_; - -}; -</PRE> -<HR WIDTH="100%"> -<P> -This is basically the same as the <i>DataBase</i> in the previous -tutorial but I've changed the name to be more generic. The feeling is -that a <i>Data</i> object would be a C struct but an <i>Work</i> -object would be a class with methods. -<P> -Now that you know what we'll be putting into the queue, lets go to the -next page where I specialize the ACE_Message_Block. -<P> -<HR WIDTH="100%"> -<P> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/012/page03.html b/docs/tutorials/012/page03.html deleted file mode 100644 index 2a952a114fa..00000000000 --- a/docs/tutorials/012/page03.html +++ /dev/null @@ -1,100 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 012</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 012</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing classes through ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -In the previous tutorial we moved our complex data into the queue by -copy()ing it directly into the message block's data area. I hope that -most readers got a queasy feeling when I did that. It just isn't a -good idea... -<P> -A better idea would be to teach the message queue about our data types -(or at least a baseclass) so that it can more efficiently handle things: -<P> -<HR WIDTH="100%"> -<PRE> -/* - We derive a Message_Block from ACE_Message_Block and teach it about - our Unit_Of_Work object. When our task's svc() method pulls a block - out of the queue, it can then invoke the virtual methods of the work - object safely. In this implementation we've also retained the - original ACE_Message_Block functionallity so that we can use the - underlying ACE_Data_Block objects to store data other than our - Unit_Of_Work. -*/ -class Message_Block : public ACE_Message_Block -{ -public: - typedef ACE_Message_Block inherited; - - /* - Construct our underlying ACE_Message_Block with the requested - data size and initialize our Unit_Of_Work pointer with the - given object instance. Note that this Message_Block instance - now assumes ownership of the Unit_Of_Work and will delete it - when the Message_Block is deleted. - */ - Message_Block( size_t size, Unit_Of_Work * _data ) - : inherited(size), data_(_data) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Message_Block ctor 0x%x for 0x%x\n", (void *) this, data_)); - } - - ~Message_Block(void) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Message_Block dtor 0x%x for 0x%x\n", (void *) this, data_)); - delete data_; - } - - /* - Return the Unit_Of_Work so that the task can invoke methods on - it. - */ - Unit_Of_Work * data(void) - { - return this->data_; - } - -protected: - Unit_Of_Work * data_; - - /* - Disallow these very dangerous operations. - If we were to copy a Message_Block object then the data_ - pointer would get copied and we would eventually end up - deleting the same object multiple times! That's not good. By - preventing the copy, we can avoid this. - */ - Message_Block &operator= (const Message_Block &); - Message_Block (const Message_Block &); -}; -</PRE> -<HR WIDTH="100%"> -<P> -Ok, this looks pretty good. We just construct our specialized -Message_Block instead of the generic ACE_Message_Block and let it -carry our data along. When our application is done with the message -block and release()es it, we know that our work object will also be -taken care of. -<P> -Let's now go to main() and see what we had to change there to use this -specialization. -<P> -<HR WIDTH="100%"> -<P> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/012/page04.html b/docs/tutorials/012/page04.html deleted file mode 100644 index b83dd9e6ca2..00000000000 --- a/docs/tutorials/012/page04.html +++ /dev/null @@ -1,124 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 012</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 012</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing classes through ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -Ok, finally we get to main(). Sorry for the diversion but it was -important to lay some of that groundwork before getting here. -<P> -<HR WIDTH="100%"> -<PRE> -/* - I want to be sure that our Task object gets destructed correctly, so - I'll do most of the application 'work' in run_test() instead of - main() -*/ -int run_test (int iterations, int threads) -{ - /* - Create the Task which is our thread pool for doing work - */ - Task task; - - if (task.open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - /* - Give the Task a chance to enter it's svc() method. This isn't - really necessary and you probably wouldn't do it in a real - application but it makes the output more interesting. - */ - ACE_OS::sleep (ACE_Time_Value (1)); - - for (int i = 0; i < iterations; ++i) - { - /* - Construct a Work object that we'll put into the Queue. Give it - the iteration number so that it can identify itself in the output. - */ - Work * data = new Work(i); - - /* - Create a block that contains our Work object but also has - enough room for a text message. - */ - Message_Block *message = new Message_Block (128, data); - - /* - As before, put a text message into the block. - */ - ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i); - message->wr_ptr (strlen (message->rd_ptr ())+1); - - /* - Add the work to our thread pool - */ - if (task.putq (message) == -1) - { - break; - } - } - - /* - Insert a HANGUP message block to tell the thread pool to shut - itself down. - */ - Message_Block *message = new Message_Block (0,0); - message->msg_type (ACE_Message_Block::MB_HANGUP); - task.putq (message); - - /* - Wait for the all threads of the Task to exit. It is rather rude - to let the Task go out of scope without doing this first. - */ - task.wait (); - - return (0); -} - -int main (int argc, char *argv[]) -{ - /* - Give the user a chance to override the default number of - iterations and pool threads. - */ - int iterations = argc > 1 ? atoi (argv[1]) : 4; - int threads = argc > 2 ? atoi (argv[2]) : 2; - - /* - Use the function above to do the actual test. As I said, this - lets us see the Task go out of scope and destruct before our - "exiting" message below. - */ - (void) run_test (iterations, threads); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n")); - - exit (0); -} -</PRE> -<HR WIDTH="100%"> -<P> -That certainly looks cleaner than the previous approach! If you -blink, you'll miss the part where the Work object goes into the Queue. -<P> -<HR WIDTH="100%"> -<P> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/012/page05.html b/docs/tutorials/012/page05.html deleted file mode 100644 index 236100f5c82..00000000000 --- a/docs/tutorials/012/page05.html +++ /dev/null @@ -1,211 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 012</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 012</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing classes through ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -The Task is the only object we've not been through yet. I'll go ahead -and show both the header and cpp on this one page since the header -isn't very large. -<P> -<HR WIDTH="100%"> -<PRE> - -/* - This is our basic thread-pool Task. We have a choice of pool size - on the open() and the usual svc() and close() methods. - - A new addition is the ACE_Barrier object. This will allow the - synchronization of our svc() methods so that they all start at the - "same" time. The normal case may allow one thread to start working - earlier than others. There's no real harm in it but you can get - better "work by thread" statistics if they start out together. -*/ -class Task : public ACE_Task < ACE_MT_SYNCH > -{ -public: - - typedef ACE_Task < ACE_MT_SYNCH > inherited; - - Task (void); - ~Task (void); - - int open (int threads = 1); - - int svc (void); - - int close (u_long flags = 0); - -protected: - ACE_Barrier * barrier_; -}; -</PRE> -<HR WIDTH="50%"> -<PRE> -/* - Boring default constructor. Be sure our barrier_ is initialized in - case we get destructed before opened. -*/ -Task::Task (void) -: barrier_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task ctor 0x%x\n", (void *) this)); -} - -/* - You'll see in the svc() method that when we get a shutdown request, - we always putq() it back into our message queue. The last thread in - the pool will do this also and result in there always being one - shutdown request left in the queue when we get here. Just to be - polite, we'll go ahead and get that message and release it. - - We also delete the barrier_ object we used to synch the svc() - methods. -*/ -Task::~Task (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task dtor 0x%x\n", (void *) this)); - - ACE_Message_Block *message; - this->getq (message); - message->release (); - - delete barrier_; -} - -/* - The ACE_Barrier needs to know how many threads it will be working - for. For that reason, we have to put off it's construction until we - get here. We then pass the thread count through to our base class' - activate(). -*/ -int Task::open (int threads) -{ - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} - -/* - We don't really do anything here but I wanted to provide a message - in the output. -*/ -int Task::close (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task close 0x%x\n", (void *) this)); - return inherited::close (flags); -} - -/* - Now the svc() method where everything interesting happens. -*/ -int Task::svc (void) -{ - /* - All of the threads will block here until the last thread - arrives. They will all then be free to begin doing work. - */ - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %u\n", (void *) this, ACE_Thread::self ())); - - // Where we getq() the message - ACE_Message_Block *message; - // What we really put into the queue is a Message_Block, so we'll - // cast the 'message' to 'message_block' after getting it. I'm - // going through some extra steps here just to be explicit - Message_Block * message_block; - // The baseclass of the work object we put into the queue. Notice - // that we can use this and not bother with the Work object at all. - Unit_Of_Work * unit_of_work; - - while (1) - { - // Get the message... - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); - } - - // Is it a shutdown request? - if (message->msg_type () == ACE_Message_Block::MB_HANGUP) - { - // Send the shutdown to all of our pool peers - this->putq (message); - break; - } - - // Cast the pointer to our specialized Message_Block. We could - // have done this at the getq() call but I wanted to be explicit - // about what we're doing here - message_block = (Message_Block*)message; - - /* - Since we left alone the ACE_Data_Block used by the - Message_Block we have chosen to use it to send arbitrary data - as well. - */ - const char *cp = message_block->rd_ptr (); - // Don't forget to skip the NULL we inserted - message_block->rd_ptr (strlen (cp) + 1); - - /* - Get the Unit_Of_Work pointer out of our specialized - Message_Block. Since the methods of interest are virtual, we - don't have to know what kind of work we're to do. - */ - unit_of_work = message_block->data(); - - /* - Invoke a couple of method calls on the object we constructed. - */ - unit_of_work->who_am_i (); - unit_of_work->what_am_i (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block 0x%x contains (%s)\n", (void *) message, cp)); - - /* - Pretend that the work takes a little time to process. This - prevents one thread from getting all of the action. In a real - system you wouldn't need to do this since the work really - would take time to complete. - */ - ACE_OS::sleep (ACE_Time_Value (0, 5000)); - - /* - Release the message block and allow the unit of work to also go - away. - */ - message->release (); - } - - return (0); -} -</PRE> -<HR WIDTH="100%"> -<P> -Like main() this is actually simpler than the previous tutorial. It's -much cleaner to carry around a pointer to the object we're working -with than to try copying data. -<P> -The only complication is the new ACE_Barrier. It's a pretty simple -object that makes it easy for you to synch threads in this way. You -could do some fancy tricks with mutexes, counters & semaphores but why -bother when the Barrier already exists. -<P> -<HR WIDTH="100%"> -<P> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/012/page06.html b/docs/tutorials/012/page06.html deleted file mode 100644 index f7282da57c9..00000000000 --- a/docs/tutorials/012/page06.html +++ /dev/null @@ -1,33 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 012</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 012</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Passing classes through ACE_Message_Queue</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -Once again, we come to the end of a tutorial. By creating a simple -specialization of ACE_Message_Block, we've been able to remove a lot -of complexity and erorr potential from our previous implementation. -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="message_queue.cpp">message_queue.cpp</A> -<LI><A HREF="data.h">data.h</A> -<LI><A HREF="task.h">task.h</A> -<LI><A HREF="task.cpp">task.cpp</A> -</UL> -<P> -<HR WIDTH="100%"> -<P> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>]</CENTER> - -</BODY> -</HTML> diff --git a/docs/tutorials/012/task.cpp b/docs/tutorials/012/task.cpp deleted file mode 100644 index 5c7a382db16..00000000000 --- a/docs/tutorials/012/task.cpp +++ /dev/null @@ -1,144 +0,0 @@ - -// $Id$ - -#include "task.h" -#include "data.h" - -/* - Boring default constructor. Be sure our barrier_ is initialized in - case we get destructed before opened. -*/ -Task::Task (void) -: barrier_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task ctor 0x%x\n", (void *) this)); -} - -/* - You'll see in the svc() method that when we get a shutdown request, - we always putq() it back into our message queue. The last thread in - the pool will do this also and result in there always being one - shutdown request left in the queue when we get here. Just to be - polite, we'll go ahead and get that message and release it. - - We also delete the barrier_ object we used to synch the svc() - methods. -*/ -Task::~Task (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task dtor 0x%x\n", (void *) this)); - - ACE_Message_Block *message; - this->getq (message); - message->release (); - - delete barrier_; -} - -/* - The ACE_Barrier needs to know how many threads it will be working - for. For that reason, we have to put off it's construction until we - get here. We then pass the thread count through to our base class' - activate(). -*/ -int Task::open (int threads) -{ - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} - -/* - We don't really do anything here but I wanted to provide a message - in the output. -*/ -int Task::close (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task close 0x%x\n", (void *) this)); - return inherited::close (flags); -} - -/* - Now the svc() method where everything interesting happens. -*/ -int Task::svc (void) -{ - /* - All of the threads will block here until the last thread - arrives. They will all then be free to begin doing work. - */ - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %u\n", (void *) this, ACE_Thread::self ())); - - // Where we getq() the message - ACE_Message_Block *message; - // What we really put into the queue is a Message_Block, so we'll - // cast the 'message' to 'message_block' after getting it. I'm - // going through some extra steps here just to be explicit - Message_Block * message_block; - // The baseclass of the work object we put into the queue. Notice - // that we can use this and not bother with the Work object at all. - Unit_Of_Work * unit_of_work; - - while (1) - { - // Get the message... - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); - } - - // Is it a shutdown request? - if (message->msg_type () == ACE_Message_Block::MB_HANGUP) - { - // Send the shutdown to all of our pool peers - this->putq (message); - break; - } - - // Cast the pointer to our specialized Message_Block. We could - // have done this at the getq() call but I wanted to be explicit - // about what we're doing here - message_block = (Message_Block*)message; - - /* - Since we left alone the ACE_Data_Block used by the - Message_Block we have chosen to use it to send arbitrary data - as well. - */ - const char *cp = message_block->rd_ptr (); - // Don't forget to skip the NULL we inserted - message_block->rd_ptr (strlen (cp) + 1); - - /* - Get the Unit_Of_Work pointer out of our specialized - Message_Block. Since the methods of interest are virtual, we - don't have to know what kind of work we're to do. - */ - unit_of_work = message_block->data(); - - /* - Invoke a couple of method calls on the object we constructed. - */ - unit_of_work->who_am_i (); - unit_of_work->what_am_i (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Block 0x%x contains (%s)\n", (void *) message, cp)); - - /* - Pretend that the work takes a little time to process. This - prevents one thread from getting all of the action. In a real - system you wouldn't need to do this since the work really - would take time to complete. - */ - ACE_OS::sleep (ACE_Time_Value (0, 5000)); - - /* - Release the message block and allow the unit of work to also go - away. - */ - message->release (); - } - - return (0); -} diff --git a/docs/tutorials/012/task.h b/docs/tutorials/012/task.h deleted file mode 100644 index 877ac98ede5..00000000000 --- a/docs/tutorials/012/task.h +++ /dev/null @@ -1,42 +0,0 @@ - -// $Id$ - -#ifndef TASK_H -#define TASK_H - -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* - This is our basic thread-pool Task. We have a choice of pool size - on the open() and the usual svc() and close() methods. - - A new addition is the ACE_Barrier object. This will allow the - synchronization of our svc() methods so that they all start at the - "same" time. The normal case may allow one thread to start working - earlier than others. There's no real harm in it but you can get - better "work by thread" statistics if they start out together. -*/ -class Task : public ACE_Task < ACE_MT_SYNCH > -{ -public: - - typedef ACE_Task < ACE_MT_SYNCH > inherited; - - Task (void); - ~Task (void); - - int open (int threads = 1); - - int svc (void); - - int close (u_long flags = 0); - -protected: - ACE_Barrier * barrier_; -}; - -#endif diff --git a/docs/tutorials/013/013.dsp b/docs/tutorials/013/013.dsp deleted file mode 100644 index 92f6469a27e..00000000000 --- a/docs/tutorials/013/013.dsp +++ /dev/null @@ -1,132 +0,0 @@ -# Microsoft Developer Studio Project File - Name="013" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=013 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "013.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "013.mak" CFG="013 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "013 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "013 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "013 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "013 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"message_queue.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "013 - Win32 Release"
-# Name "013 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\block.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\message_queue.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\mld.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\work.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\block.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\mld.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\task.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\work.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/013/Makefile b/docs/tutorials/013/Makefile deleted file mode 100644 index eaa5766926e..00000000000 --- a/docs/tutorials/013/Makefile +++ /dev/null @@ -1,71 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = message_queue - -FILES = task block work mld - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -HDR = *.h - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - chmod +r *.html - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre *.pst > combine.shar && rm -f hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar - -.depend : # - touch .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/013/block.cpp b/docs/tutorials/013/block.cpp deleted file mode 100644 index 5dd72a2013e..00000000000 --- a/docs/tutorials/013/block.cpp +++ /dev/null @@ -1,81 +0,0 @@ - -// $Id$ - -#include "block.h" - -/* - Construct a Dat_Block to contain a unit of work. Note the careful - construction of the baseclass to set the block type and the locking - strategy. - */ -Data_Block::Data_Block (Unit_Of_Work * _data) - : ACE_Data_Block (0, ACE_Message_Block::MB_DATA, 0, 0, new Lock (), 0, 0) - ,data_ (_data) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Data_Block ctor for 0x%x\n", (void *) this, (void *) data_)); -} - -/* - The Lock object created in the constructor is stored in the baseclass and - available through the locking_strategy() method. We can cast it's value to - our Lock object and invoke the destroy() to indicate that we want it to go - away when the lock is released. - */ -Data_Block::~Data_Block (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Data_Block dtor for 0x%x\n", (void *) this, (void *) data_)); - ((Lock *) locking_strategy ())->destroy (); - delete data_; -} - -/* - Return the data - */ -Unit_Of_Work *Data_Block::data (void) -{ - return this->data_; -} - -Data_Block:: Lock::Lock (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Lock ctor\n", (void *) this)); -} - -Data_Block:: Lock::~Lock (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Lock dtor\n", (void *) this)); -} - -/* - Delete ourselves to prevent any memory leak - */ -int Data_Block::Lock::destroy (void) -{ - delete this; - return (0); -} - -/* - Create an baseclass unit of work when we instantiate a hangup message. - */ -Message_Block::Message_Block (void) - :ACE_Message_Block (new Data_Block (new Unit_Of_Work ())) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Message_Block ctor for shutdown\n", (void *) this)); - this->msg_type (MB_HANGUP); -} - -/* - Store the unit of work in a Data_Block and initialize the baseclass with - that data. - */ -Message_Block::Message_Block (Unit_Of_Work * _data) - :ACE_Message_Block (new Data_Block (_data)) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Message_Block ctor for 0x%x\n", (void *) this, (void *) _data)); -} - -Message_Block::~Message_Block (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Message_Block dtor\n", (void *) this)); -} diff --git a/docs/tutorials/013/block.h b/docs/tutorials/013/block.h deleted file mode 100644 index e6c02e1e725..00000000000 --- a/docs/tutorials/013/block.h +++ /dev/null @@ -1,84 +0,0 @@ - -// $Id$ - -#ifndef BLOCK_H -#define BLOCK_H - -#include "ace/Message_Block.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Synch.h" -#include "mld.h" -#include "work.h" - -/* - In this Tutorial, we derive from ACE_Data_Block for our special data. With - the possiblilty that our Task object may forward the unit of work on to - another thread pool, we have to make sure that the data object doesn't go - out of scope unexpectedly. An ACE_Message_Block will be deleted as soon as - it's release() method is called but the ACE_Data_Blocks it uses are - reference counted and only delete when the last reference release()es the - block. We use that trait to simplify our object memory management. - */ -class Data_Block : public ACE_Data_Block -{ -public: - typedef ACE_Data_Block inherited; - - // Create a data block with a unit of work to be done - Data_Block (Unit_Of_Work * _data); - - ~Data_Block (void); - - // Returns the work pointer - Unit_Of_Work *data (void); - -protected: - Unit_Of_Work * data_; - MLD; // Our memory leak detector - - // The ACE_Data_Block allows us to choose a locking strategy - // for making the reference counting thread-safe. The - // ACE_Lock_Adaptor<> template adapts the interface of a - // number of lock objects so that the ACE_Message_Block will - // have an interface it can use. - class Lock : public ACE_Lock_Adapter < ACE_Mutex > - { - public: - typedef ACE_Lock_Adapter < ACE_Mutex > inherited; - - Lock (void); - ~Lock (void); - - // destroy() will be called to explicitly delete the - // lock when we no longer need it. The method will then - // cleanup to prevent any memory leaks. - int destroy (void); - - protected: - MLD; - }; -}; - -/* - This simple derivative of ACE_Message_Block will construct our Data_Block - object to contain a unit of work. - */ -class Message_Block : public ACE_Message_Block -{ -public: - typedef ACE_Message_Block inherited; - - Message_Block (void); - Message_Block (Unit_Of_Work * _data); - - ~Message_Block (void); - -protected: - MLD; -}; - -#endif diff --git a/docs/tutorials/013/combine.shar b/docs/tutorials/013/combine.shar deleted file mode 100644 index e67be9253c5..00000000000 --- a/docs/tutorials/013/combine.shar +++ /dev/null @@ -1,634 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-11-15 12:09 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/013'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 386 -rw-rw-r-- hdr -# 89 -rw-rw-r-- bodies -# 976 -rw-rw-r-- page01.pre -# 432 -rw-rw-r-- page02.pre -# 1426 -rw-rw-r-- page03.pre -# 1049 -rw-rw-r-- page04.pre -# 268 -rw-rw-r-- page05.pre -# 914 -rw-rw-r-- page06.pre -# 1368 -rw-rw-r-- page07.pre -# 862 -rw-rw-r-- page08.pre -# 204 -rw-rw-r-- page02.pst -# 704 -rw-rw-r-- page04.pst -# 386 -rw-rw-r-- page06.pst -# 371 -rw-rw-r-- page07.pst -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh10945; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> -SHAR_EOF - $shar_touch -am 1114225598 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -abef9831eba4051526151ff2343730d7 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 386 -eq "$shar_count" || - $echo 'hdr:' 'original size' '386,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -message_queue.cpp -mld.h mld.cpp -block.h -block.cpp -task.h task.cpp -work.h work.cpp -SHAR_EOF - $shar_touch -am 1114230198 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -826e1e15e593f64228b867cb6143f179 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 89 -eq "$shar_count" || - $echo 'bodies:' 'original size' '89,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -My intent with this tutorial was to derive from ACE_Data_Block instead -of ACE_Message_Block so that we could leverage the reference counting -nature of that object. -<P> -Along the way, I sort of got distracted... What I ended up with is a -poor excuse for ACE_Stream that implements a simple state machine. -<P> -The application is built around a thread pool where the pool's svc() -method takes work units from the message queue for processing. As -each unit is taken from the queue, the process() method is invoked to -do some work. The twist is that after processing the message, we -enqueue it into another thread pool to do more work. This continues -through a chain of thread pools until the last where the unit's fini() -method is called for finishing up any outstanding work. -<P> -The chain of thread pools is uni-directional using a singly-linked -list of Task derivatives. Each pool has the same number of tasks in -order to keep things simple. -SHAR_EOF - $shar_touch -am 1114225598 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -391c8a4163bf85a87526b476ac9f0f99 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 976 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '976,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -We'll go back to our tradition of looking at main() first. The only -change here from our "normal" thread pool is the ability to specify -the number of subtasks for the pool. (Each subtask is another thread -pool in the chain. I suppose I should have named that better...) -I've still got the custom Message_Block so that, at this level, we -don't even know about custom Data_Blocks. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1114225598 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -6f4a2e24d7d776b1ec17a07f00f409f8 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 432 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '432,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -I did eventually create that ACE_Data_Block derivative that I wanted. -My purpose in doing so was to use the reference-counting -that is provided by ACE_Data_Block and ACE_Message_Block interactions. -X When you're working with an object in a single -thread, it's generally not so difficult to manage it's lifetime. -That is, it doesn't tend to go out of scope or get destroyed unless -you do it on purpose. -<P> -On the other hand, if you're passing data between several threads, it -is easy to loose track of who "owns" the data at any one time. All -too frequently, data will be deleted by one thread while another is -still using it. Reference counting can prevent that. The rule of -thumb is that you increment the reference count of the object when you -hand it off to a new thread. You then decrement the count when you're -done with the object and let the object delete itself when there are -no more references. -<P> -To prove that all of that works correctly in the tutorial, I've -created a cheap Memory Leak Detector object. All mld instances -reference a thread-safe counter that is incremented when the mld is -constructed and decremented when destructed. I then insert an mld -into each of my dynamically created objects. If I get to the end of -main() and the counter isn't zero then I either didn't delete enough -or I deleted too many times. -<P> -Simple, cheap, effective. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1114225598 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -e4c0dfb0a761a258adeba509ac6c2062 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 1426 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '1426,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -Let's look now at the changes to our ACE_Message_Block derivative and -the new ACE_Data_Block derivative. -<P> -The important thing to remember is that the data block (not the -message block) is reference counted. When you instantiate a new -ACE_Message_Block, it will create one or more ACE_Data_Block objects -to contain the data you need. Optionally, you can provide it with a -pointer to a data block. -<P> -When you finish with a message block, you should use the release() -method to make it go away. Do not ever <em>delete</em> an instance of -a message block! When you invoke release(), the message block will -invoke release() on the data block(s) it contains. If the block's -reference count goes to zero as a result then the block will <em>delete</em> -itself. -<P> -To increment the reference count of a data block, use the -duplicate() method of the message block (or blocks) to get a new -message block referencing the same data block. This is very efficient -since the actual data is not copied. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1114225598 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -05d0560194222144a3a599b4d88990ff page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 1049 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '1049,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -On this page we have the code for the Data_Block and Message_Block -objects. As you probably suspect from the header on the previous -page, the complicated part is in the construction and destruction of -the Data_Block. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1114225598 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -a95fdcd3db2356b091228728f4f3f130 page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 268 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '268,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -Let's take a look now at the new Task object. This will obviously be -different from the Tasks we've created before but I think you'll be -surprised at how relatively simple it actually is. -<P> -Remember that the goal of this tutorial was to use the reference -counting abilities of the ACE_Data_Block. The only way to show that -effectively is to have a data block passed between different threads. -A thread pool isn't really going to do that so, instead, our new Task -can be part of a chain of tasks. In that way, each Task can pass the -data on to another and satisfy our need for moving the ACE_Data_Block -around. -If we've done the reference counting correctly then none of our tasks -will be trying to work with deleted data and we won't have any memory -leaks at the end. -<P> -There's not much to the header, so I've included it and the cpp file -on this one page. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1114225698 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pre:' 'MD5 check failed' -a4c9b50df3240c5134733d2033fd5f03 page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 914 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '914,' 'current size' "$shar_count!" - fi -fi -# ============= page07.pre ============== -if test -f 'page07.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page07.pre' '(file already exists)' -else - $echo 'x -' extracting 'page07.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page07.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -I've been trying to justify the chain of tasks by talking about a -Work object that implements a state machine. The idea is that your -Work object has to perform a series of discrete steps to complete it's -function. Traditionally, all of those steps would take place in one -thread of execution. That thread would probably be one from a Task -thread pool. -<P> -Suppose, however, that some of those steps spend a lot of time waiting -for disk IO. You could find that all of your thread-pool threads -are just sitting there waiting for the disk. You might then be -tempted to increase the thread pool size to get more work through. -However, if some of the stages are memory intensive, you could run out -of memory if all of the workers get to that state at the same time. -<P> -One solution might be to have different thread pools for each state. -Each pool could have it's size tuned appropriately for the work that -would be done there. That's where the chain of Tasks comes in. -X In this tutorial's implementation I've taken the -easy route and set all of the thread pools to the same size but a more -realistic solution would be to set each thread pool in the chain to a -specific size as needed by that state of operation. -<P> -There's not much to this header either so I've combined it with the -cpp file as with task. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1114225698 'page07.pre' && - chmod 0664 'page07.pre' || - $echo 'restore of' 'page07.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page07.pre:' 'MD5 check failed' -9bd5ac0cf6ff9786f3f99602a282146d page07.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page07.pre'`" - test 1368 -eq "$shar_count" || - $echo 'page07.pre:' 'original size' '1368,' 'current size' "$shar_count!" - fi -fi -# ============= page08.pre ============== -if test -f 'page08.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page08.pre' '(file already exists)' -else - $echo 'x -' extracting 'page08.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page08.pre' && -X -X -<P> -<HR WIDTH="100%"> -<P> -And that's the end of another tutorial. This one is probably the most -complicated so far because I've introduced or expanded upon -a number of different -concepts. Namely: state machines, reference counting and task -chaining. I hope I didn't complicate things to the point where the -lesson got lost in the noise. As always, feel free to drop a note to -the ACE-Users mailing list if you feel that some of this could use a -little more explaination. -X -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="block.cpp">block.cpp</A> -<LI><A HREF="block.h">block.h</A> -<LI><A HREF="message_queue.cpp">message_queue.cpp</A> -<LI><A HREF="mld.cpp">mld.cpp</A> -<LI><A HREF="mld.h">mld.h</A> -<LI><A HREF="task.cpp">task.cpp</A> -<LI><A HREF="task.h">task.h</A> -<LI><A HREF="work.cpp">work.cpp</A> -<LI><A HREF="work.h">work.h</A> -</UL> -<P> -SHAR_EOF - $shar_touch -am 1114231398 'page08.pre' && - chmod 0664 'page08.pre' || - $echo 'restore of' 'page08.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page08.pre:' 'MD5 check failed' -c035c8da307bddcab1d1031f5242aadc page08.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page08.pre'`" - test 862 -eq "$shar_count" || - $echo 'page08.pre:' 'original size' '862,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pst ============== -if test -f 'page02.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pst' '(file already exists)' -else - $echo 'x -' extracting 'page02.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pst' && -<HR WIDTH="100%"> -<P> -Nothing really surprising here... Just remember that your total -number of threads is ( ( 1 + subtasks ) * threads ). You probably -don't want to get too carried away with that! -<P> -SHAR_EOF - $shar_touch -am 1114225798 'page02.pst' && - chmod 0664 'page02.pst' || - $echo 'restore of' 'page02.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pst:' 'MD5 check failed' -a8c43c5c68518f6eb8c03701d1603a92 page02.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`" - test 204 -eq "$shar_count" || - $echo 'page02.pst:' 'original size' '204,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pst ============== -if test -f 'page04.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pst' '(file already exists)' -else - $echo 'x -' extracting 'page04.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pst' && -<HR WIDTH="100%"> -<P> -One of the most difficult parts of this to get right was the Lock -object. I didn't even have it in the beginning but I soon realized -that the reference counts were getting weird. A little careful -reading of the comments and the source informed me that some sort of -locking is necessary to keep the counter sane. The simplest thing at -that point was to use the ACE_Lock_Adaptor<> to adapt ACE_Mutex -appropriately. The next trick was to ensure that the lock object was -destroyed at the proper time to prevent both memory leaks and core -dumps. The finaly product may be a little bit intimidating at first -but it's really quite simple once you understand the motivation. -<P> -SHAR_EOF - $shar_touch -am 1114225798 'page04.pst' && - chmod 0664 'page04.pst' || - $echo 'restore of' 'page04.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pst:' 'MD5 check failed' -325565f3f72961b842b612caeb93b36a page04.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`" - test 704 -eq "$shar_count" || - $echo 'page04.pst:' 'original size' '704,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pst ============== -if test -f 'page06.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pst' '(file already exists)' -else - $echo 'x -' extracting 'page06.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pst' && -<HR WIDTH="100%"> -<P> -So you see... it wasn't really that much more complicated. We really -just have to remember to pass to <i>next_</i> when we finish working -on the data. If your Unit_Of_Work derivative is going to implement a -state machine be sure that you also implement a fini() method -<em>or</em> ensure that your chain of subtasks is large enough for all -possible states. -<P> -SHAR_EOF - $shar_touch -am 1114225798 'page06.pst' && - chmod 0664 'page06.pst' || - $echo 'restore of' 'page06.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pst:' 'MD5 check failed' -fb9a3381fc937578fe01ceca882df8be page06.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pst'`" - test 386 -eq "$shar_count" || - $echo 'page06.pst:' 'original size' '386,' 'current size' "$shar_count!" - fi -fi -# ============= page07.pst ============== -if test -f 'page07.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page07.pst' '(file already exists)' -else - $echo 'x -' extracting 'page07.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page07.pst' && -<HR> -<P> -And that is that. For a more complex machine that may want to "jump -states" you would have to set some "state information" (sorry, bad -choice of terminology again) so that process() could decide what to do -at each call. You might also modify Task::svc() so that it will -respect the return value of process() and do something useful with the -information. -<P> -SHAR_EOF - $shar_touch -am 1114231398 'page07.pst' && - chmod 0664 'page07.pst' || - $echo 'restore of' 'page07.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page07.pst:' 'MD5 check failed' -8d919ab7e0d5ff90e50cc785564b2f67 page07.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page07.pst'`" - test 371 -eq "$shar_count" || - $echo 'page07.pst:' 'original size' '371,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh10945 -exit 0 diff --git a/docs/tutorials/013/message_queue.cpp b/docs/tutorials/013/message_queue.cpp deleted file mode 100644 index 5238bd00ccb..00000000000 --- a/docs/tutorials/013/message_queue.cpp +++ /dev/null @@ -1,88 +0,0 @@ - -// $Id$ - -#include "mld.h" -#include "task.h" -#include "work.h" -#include "block.h" - -int run_test (int iterations, int threads, int subtasks) -{ - // Create a task with some subtasks. Each Task is a thread - // pool of 'threads' size. If a task has a subtask, it will - // forward the unit of work to the subtask when finished. See - // task.{h|cpp} for more details. - Task *task = new Task (subtasks); - - if (task->open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - } - - // Give the threads a chance to get ready. - ACE_OS::sleep (ACE_Time_Value (1)); - - for (int i = 0; i < iterations; ++i) - { - // Create a custom message block that can contain our Work object - Message_Block *message = new Message_Block (new Work (i)); - - // Put the "unit of work" into the message queue - if (task->putq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putq"), -1); - } - } - - // The default constructor of our custom message block will - // insert a message telling our task to shutdown. - Message_Block *message = new Message_Block (); - - // Put the shutdown request into the thread pool - if (task->putq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putq"), -1); - } - - // Wait for the task to shut down. Any subtasks will also be - // waited for. - task->wait (); - - // Delete our Task to prevent a memory leak - delete task; - - // Ask our memory leak detector if things are OK - if (MLD_COUNTER != 0) - { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Memory Leak! (counter = %d)\n",MLD_COUNTER)); - } - - return (0); -} - -int main (int argc, char *argv[]) -{ - // Number of Work objects to put into the Task pool - int iterations = argc > 1 ? atoi (argv[1]) : 4; - // Number of threads for each Task - int threads = argc > 2 ? atoi (argv[2]) : 2; - // Number of tasks to chain after the primary task - int subtasks = argc > 3 ? atoi (argv[3]) : 1; - - (void) run_test (iterations, threads, subtasks); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Application exiting\n")); - - return (0); -} -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Guard < ACE_Mutex >; -template class ACE_Lock_Adapter < ACE_Mutex >; -template class ACE_Atomic_Op < ACE_Mutex, int >; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Guard<ACE_Mutex>; -#pragma instantiate ACE_Lock_Adapter<ACE_Mutex>; -#pragma instantiate ACE_Atomic_Op<ACE_Mutex, int>; -#endif /* - ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION - */ diff --git a/docs/tutorials/013/mld.cpp b/docs/tutorials/013/mld.cpp deleted file mode 100644 index ca12d9eb514..00000000000 --- a/docs/tutorials/013/mld.cpp +++ /dev/null @@ -1,23 +0,0 @@ - -// $Id$ - -#include "mld.h" - -ACE_Atomic_Op < ACE_Mutex, int >mld::counter_ (0); - -// Increment the counter when a new mld is created... -mld::mld (void) -{ - ++counter_; -} - -// and decrement it when the object is destructed. -mld::~mld (void) -{ - --counter_; -} - -int mld::value (void) -{ - return counter_.value (); -} diff --git a/docs/tutorials/013/mld.h b/docs/tutorials/013/mld.h deleted file mode 100644 index 015b1a77eaa..00000000000 --- a/docs/tutorials/013/mld.h +++ /dev/null @@ -1,49 +0,0 @@ - -// $Id$ - -#ifndef MLD_H -#define MLD_H - -#include "ace/Synch.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Singleton.h" - -/* - This is a cheap memory leak detector. Each class I want to watch over - contains an mld object. The mld object's ctor increments a global counter - while the dtor decrements it. If the counter is non-zero when the program - is ready to exit then there may be a leak. - */ - -class mld -{ -public: - mld (void); - ~mld (void); - - static int value (void); - -protected: - static ACE_Atomic_Op < ACE_Mutex, int >counter_; -}; - -// ================================================ - -/* - Just drop 'MLD' anywhere in your class definition to get cheap memory leak - detection for your class. - */ -#define MLD mld mld_ - -/* - Use 'MLD_COUNTER' in main() to see if things are OK. - */ -#define MLD_COUNTER mld::value() - -// ================================================ - -#endif diff --git a/docs/tutorials/013/page01.html b/docs/tutorials/013/page01.html deleted file mode 100644 index 251a053aadc..00000000000 --- a/docs/tutorials/013/page01.html +++ /dev/null @@ -1,36 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -My intent with this tutorial was to derive from ACE_Data_Block instead -of ACE_Message_Block so that we could leverage the reference counting -nature of that object. -<P> -Along the way, I sort of got distracted... What I ended up with is a -poor excuse for ACE_Stream that implements a simple state machine. -<P> -The application is built around a thread pool where the pool's svc() -method takes work units from the message queue for processing. As -each unit is taken from the queue, the process() method is invoked to -do some work. The twist is that after processing the message, we -enqueue it into another thread pool to do more work. This continues -through a chain of thread pools until the last where the unit's fini() -method is called for finishing up any outstanding work. -<P> -The chain of thread pools is uni-directional using a singly-linked -list of Task derivatives. Each pool has the same number of tasks in -order to keep things simple. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/013/page02.html b/docs/tutorials/013/page02.html deleted file mode 100644 index 7fca9f39265..00000000000 --- a/docs/tutorials/013/page02.html +++ /dev/null @@ -1,122 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -We'll go back to our tradition of looking at main() first. The only -change here from our "normal" thread pool is the ability to specify -the number of subtasks for the pool. (Each subtask is another thread -pool in the chain. I suppose I should have named that better...) -I've still got the custom Message_Block so that, at this level, we -don't even know about custom Data_Blocks. -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>mld.h</font>" -<font color=blue>#include</font> "<font color=green>task.h</font>" -<font color=blue>#include</font> "<font color=green>work.h</font>" -<font color=blue>#include</font> "<font color=green>block.h</font>" - -int run_test (int iterations, int threads, int subtasks) -{ - <font color=red>// Create a task with some subtasks. Each Task is a thread</font> - <font color=red>// pool of 'threads' size. If a task has a subtask, it will</font> - <font color=red>// forward the unit of work to the subtask when finished. See </font> - <font color=red>// task.{h|cpp} for more details.</font> - Task *task = new Task (subtasks); - - if (task->open (threads) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>open</font>"), -1); - } - - <font color=red>// Give the threads a chance to get ready.</font> - <font color=#008888>ACE_OS::sleep</font> (ACE_Time_Value (1)); - - for (int i = 0; i < iterations; ++i) - { - <font color=red>// Create a custom message block that can contain our Work object</font> - Message_Block *message = new Message_Block (new Work (i)); - - <font color=red>// Put the "<font color=green>unit of work</font>" into the message queue</font> - if (task->putq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>putq</font>"), -1); - } - } - - <font color=red>// The default constructor of our custom message block will</font> - <font color=red>// insert a message telling our task to shutdown.</font> - Message_Block *message = new Message_Block (); - - <font color=red>// Put the shutdown request into the thread pool</font> - if (task->putq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>putq</font>"), -1); - } - - <font color=red>// Wait for the task to shut down. Any subtasks will also be</font> - <font color=red>// waited for.</font> - task->wait (); - - <font color=red>// Delete our Task to prevent a memory leak</font> - delete task; - - <font color=red>// Ask our memory leak detector if things are OK</font> - if (MLD_COUNTER != 0) - { - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Memory Leak! (counter = %d)\n</font>",MLD_COUNTER)); - } - - return (0); -} - -int main (int argc, char *argv[]) -{ - <font color=red>// Number of Work objects to put into the Task pool</font> - int iterations = argc > 1 ? atoi (argv[1]) : 4; - <font color=red>// Number of threads for each Task</font> - int threads = argc > 2 ? atoi (argv[2]) : 2; - <font color=red>// Number of tasks to chain after the primary task</font> - int subtasks = argc > 3 ? atoi (argv[3]) : 1; - - (void) run_test (iterations, threads, subtasks); - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Application exiting\n</font>")); - - exit (0); -} -<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>) -template class ACE_Guard < ACE_Mutex >; -template class ACE_Lock_Adapter < ACE_Mutex >; -template class ACE_Atomic_Op < ACE_Mutex, int >; -<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Guard<ACE_Mutex>; -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Lock_Adapter<ACE_Mutex>; -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Atomic_Op<ACE_Mutex, int>; -<font color=blue>#endif</font> <font color=red>/* - ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION - */</font> -</PRE> -<HR WIDTH="100%"> -<P> -Nothing really surprising here... Just remember that your total -number of threads is ( ( 1 + subtasks ) * threads ). You probably -don't want to get too carried away with that! -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/013/page03.html b/docs/tutorials/013/page03.html deleted file mode 100644 index 43a2d0832ca..00000000000 --- a/docs/tutorials/013/page03.html +++ /dev/null @@ -1,124 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -I did eventually create that ACE_Data_Block derivative that I wanted. -My purpose in doing so was to use the reference-counting -that is provided by ACE_Data_Block and ACE_Message_Block interactions. - When you're working with an object in a single -thread, it's generally not so difficult to manage it's lifetime. -That is, it doesn't tend to go out of scope or get destroyed unless -you do it on purpose. -<P> -On the other hand, if you're passing data between several threads, it -is easy to loose track of who "owns" the data at any one time. All -too frequently, data will be deleted by one thread while another is -still using it. Reference counting can prevent that. The rule of -thumb is that you increment the reference count of the object when you -hand it off to a new thread. You then decrement the count when you're -done with the object and let the object delete itself when there are -no more references. -<P> -To prove that all of that works correctly in the tutorial, I've -created a cheap Memory Leak Detector object. All mld instances -reference a thread-safe counter that is incremented when the mld is -constructed and decremented when destructed. I then insert an mld -into each of my dynamically created objects. If I get to the end of -main() and the counter isn't zero then I either didn't delete enough -or I deleted too many times. -<P> -Simple, cheap, effective. -<P> -<HR WIDTH="100%"> -<PRE> -<HR width=50%><P><center>mld.h</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>MLD_H</font> -<font color=blue>#define</font> <font color=purple>MLD_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Synch.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>ace/Singleton.h</font>" - -<font color=red>/* - This is a cheap memory leak detector. Each class I want to watch over - contains an mld object. The mld object's ctor increments a global counter - while the dtor decrements it. If the counter is non-zero when the program - is ready to exit then there may be a leak. - */</font> - -class mld -{ -public: - mld (void); - ~mld (void); - - static int value (void); - -protected: - static ACE_Atomic_Op < ACE_Mutex, int >counter_; -}; - -<font color=red>// ================================================</font> - -<font color=red>/* - Just drop 'MLD' anywhere in your class definition to get cheap memory leak - detection for your class. - */</font> -<font color=blue>#define</font> <font color=purple>MLD</font> mld mld_ - -<font color=red>/* - Use 'MLD_COUNTER' in main() to see if things are OK. - */</font> -<font color=blue>#define</font> <font color=purple>MLD_COUNTER</font> <font color=#008888>mld::value</font>() - -<font color=red>// ================================================</font> - -<font color=blue>#endif</font> -</PRE> -<PRE> -<HR width=50%><P><center>mld.cpp</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>mld.h</font>" - -ACE_Atomic_Op < ACE_Mutex, int ><font color=#008888>mld::counter_</font> (0); - -<font color=red>// Increment the counter when a new mld is created...</font> -<font color=#008888>mld::mld</font> (void) -{ - ++counter_; -} - -<font color=red>// and decrement it when the object is destructed.</font> -<font color=#008888>mld::~mld</font> (void) -{ - --counter_; -} - -int <font color=#008888>mld::value</font> (void) -{ - return counter_.value (); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/013/page04.html b/docs/tutorials/013/page04.html deleted file mode 100644 index a52dbdba587..00000000000 --- a/docs/tutorials/013/page04.html +++ /dev/null @@ -1,139 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -Let's look now at the changes to our ACE_Message_Block derivative and -the new ACE_Data_Block derivative. -<P> -The important thing to remember is that the data block (not the -message block) is reference counted. When you instantiate a new -ACE_Message_Block, it will create one or more ACE_Data_Block objects -to contain the data you need. Optionally, you can provide it with a -pointer to a data block. -<P> -When you finish with a message block, you should use the release() -method to make it go away. Do not ever <em>delete</em> an instance of -a message block! When you invoke release(), the message block will -invoke release() on the data block(s) it contains. If the block's -reference count goes to zero as a result then the block will <em>delete</em> -itself. -<P> -To increment the reference count of a data block, use the -duplicate() method of the message block (or blocks) to get a new -message block referencing the same data block. This is very efficient -since the actual data is not copied. -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>BLOCK_H</font> -<font color=blue>#define</font> <font color=purple>BLOCK_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Message_Block.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>ace/Synch.h</font>" -<font color=blue>#include</font> "<font color=green>mld.h</font>" -<font color=blue>#include</font> "<font color=green>work.h</font>" - -<font color=red>/* - In this Tutorial, we derive from ACE_Data_Block for our special data. With - the possiblilty that our Task object may forward the unit of work on to - another thread pool, we have to make sure that the data object doesn't go - out of scope unexpectedly. An ACE_Message_Block will be deleted as soon as - it's release() method is called but the ACE_Data_Blocks it uses are - reference counted and only delete when the last reference release()es the - block. We use that trait to simplify our object memory management. - */</font> -class Data_Block : public ACE_Data_Block -{ -public: - typedef ACE_Data_Block inherited; - - <font color=red>// Create a data block with a unit of work to be done</font> - Data_Block (Unit_Of_Work * _data); - - ~Data_Block (void); - - <font color=red>// Returns the work pointer</font> - Unit_Of_Work *data (void); - -protected: - Unit_Of_Work * data_; - MLD; <font color=red>// Our memory leak detector</font> - - <font color=red>// The ACE_Data_Block allows us to choose a locking strategy</font> - <font color=red>// for making the reference counting thread-safe. The</font> - <font color=red>// ACE_Lock_Adaptor<> template adapts the interface of a</font> - <font color=red>// number of lock objects so that the ACE_Message_Block will</font> - <font color=red>// have an interface it can use.</font> - class Lock : public ACE_Lock_Adapter < ACE_Mutex > - { - public: - typedef ACE_Lock_Adapter < ACE_Mutex > inherited; - - Lock (void); - ~Lock (void); - - <font color=red>// destroy() will be called to explicitly delete the</font> - <font color=red>// lock when we no longer need it. The method will then</font> - <font color=red>// cleanup to prevent any memory leaks.</font> - int destroy (void); - - protected: - MLD; - }; -}; - -<font color=red>/* - This simple derivative of ACE_Message_Block will construct our Data_Block - object to contain a unit of work. - */</font> -class Message_Block : public ACE_Message_Block -{ -public: - typedef ACE_Message_Block inherited; - - Message_Block (void); - Message_Block (Unit_Of_Work * _data); - - ~Message_Block (void); - -protected: - MLD; -}; - -<font color=blue>#endif</font> -</PRE> -<HR WIDTH="100%"> -<P> -One of the most difficult parts of this to get right was the Lock -object. I didn't even have it in the beginning but I soon realized -that the reference counts were getting weird. A little careful -reading of the comments and the source informed me that some sort of -locking is necessary to keep the counter sane. The simplest thing at -that point was to use the ACE_Lock_Adaptor<> to adapt ACE_Mutex -appropriately. The next trick was to ensure that the lock object was -destroyed at the proper time to prevent both memory leaks and core -dumps. The finaly product may be a little bit intimidating at first -but it's really quite simple once you understand the motivation. -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/013/page05.html b/docs/tutorials/013/page05.html deleted file mode 100644 index 95588ff8590..00000000000 --- a/docs/tutorials/013/page05.html +++ /dev/null @@ -1,107 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -On this page we have the code for the Data_Block and Message_Block -objects. As you probably suspect from the header on the previous -page, the complicated part is in the construction and destruction of -the Data_Block. -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>block.h</font>" - -<font color=red>/* - Construct a Dat_Block to contain a unit of work. Note the careful - construction of the baseclass to set the block type and the locking - strategy. - */</font> -<font color=#008888>Data_Block::Data_Block</font> (Unit_Of_Work * _data) - : ACE_Data_Block (0, <font color=#008888>ACE_Message_Block::MB_DATA</font>, 0, 0, new Lock (), 0, 0) - ,data_ (_data) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Data_Block ctor for 0x%x\n</font>", (void *) this, (void *) data_)); -} - -<font color=red>/* - The Lock object created in the constructor is stored in the baseclass and - available through the locking_strategy() method. We can cast it's value to - our Lock object and invoke the destroy() to indicate that we want it to go - away when the lock is released. - */</font> -<font color=#008888>Data_Block::~Data_Block</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Data_Block dtor for 0x%x\n</font>", (void *) this, (void *) data_)); - ((Lock *) locking_strategy ())->destroy (); - delete data_; -} - -<font color=red>/* - Return the data - */</font> -Unit_Of_Work *<font color=#008888>Data_Block::data</font> (void) -{ - return this->data_; -} - -Data_Block:: <font color=#008888>Lock::Lock</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Lock ctor\n</font>", (void *) this)); -} - -Data_Block:: <font color=#008888>Lock::~Lock</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Lock dtor\n</font>", (void *) this)); -} - -<font color=red>/* - Delete ourselves to prevent any memory leak - */</font> -int <font color=#008888>Data_Block::Lock</font>::destroy (void) -{ - delete this; - return (0); -} - -<font color=red>/* - Create an baseclass unit of work when we instantiate a hangup message. - */</font> -<font color=#008888>Message_Block::Message_Block</font> (void) - :ACE_Message_Block (new Data_Block (new Unit_Of_Work ())) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Message_Block ctor for shutdown\n</font>", (void *) this)); - this->msg_type (MB_HANGUP); -} - -<font color=red>/* - Store the unit of work in a Data_Block and initialize the baseclass with - that data. - */</font> -<font color=#008888>Message_Block::Message_Block</font> (Unit_Of_Work * _data) - :ACE_Message_Block (new Data_Block (_data)) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Message_Block ctor for 0x%x\n</font>", (void *) this, (void *) _data)); -} - -<font color=#008888>Message_Block::~Message_Block</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Message_Block dtor\n</font>", (void *) this)); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/013/page06.html b/docs/tutorials/013/page06.html deleted file mode 100644 index 66a71581c70..00000000000 --- a/docs/tutorials/013/page06.html +++ /dev/null @@ -1,298 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -Let's take a look now at the new Task object. This will obviously be -different from the Tasks we've created before but I think you'll be -surprised at how relatively simple it actually is. -<P> -Remember that the goal of this tutorial was to use the reference -counting abilities of the ACE_Data_Block. The only way to show that -effectively is to have a data block passed between different threads. -A thread pool isn't really going to do that so, instead, our new Task -can be part of a chain of tasks. In that way, each Task can pass the -data on to another and satisfy our need for moving the ACE_Data_Block -around. -If we've done the reference counting correctly then none of our tasks -will be trying to work with deleted data and we won't have any memory -leaks at the end. -<P> -There's not much to the header, so I've included it and the cpp file -on this one page. -<P> -<HR WIDTH="100%"> -<PRE> -<HR width=50%><P><center>task.h</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>TASK_H</font> -<font color=blue>#define</font> <font color=purple>TASK_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Task.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>mld.h</font>" - -<font color=red>/* - This is much like the Task we've used in the past for implementing a thread - pool. This time, however, I've made the Task an element in a singly-linked - list. As the svc() method finishes the process() on a unit of work, it - will enqueue that unit of work to the next_ Task if there is one. If the - Task does not have a next_ Task, it will invoke the unit of work object's - fini() method after invoking process(). - */</font> -class Task : public ACE_Task < ACE_MT_SYNCH > -{ -public: - - typedef ACE_Task < ACE_MT_SYNCH > inherited; - - <font color=red>// Construct ourselves and an optional number of subtasks</font> - <font color=red>// chained beyond us.</font> - Task (int sub_tasks = 0); - ~Task (void); - - <font color=red>// Open the Task with the proper thread-pool size</font> - int open (int threads = 1); - - <font color=red>// Take Unit_Of_Work objects from the thread pool and invoke</font> - <font color=red>// their process() and/or fini() as appropriate.</font> - int svc (void); - - <font color=red>// Shut down the thread pool and it's associated subtasks</font> - int close (u_long flags = 0); - - <font color=red>// Wait for the pool and subtasks to close</font> - int wait (void); - -protected: - ACE_Barrier * barrier_; - Task *next_; - MLD; -}; - -<font color=blue>#endif</font> -</PRE> -<PRE> -<HR width=50%><P><center>task.cpp</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>task.h</font>" -<font color=blue>#include</font> "<font color=green>block.h</font>" -<font color=blue>#include</font> "<font color=green>work.h</font>" - -<font color=red>/* - Construct the Task with zero or more subtasks. If subtasks are requested, - we assign our next_ pointer to the first of those and let it worry about - any remaining subtasks. - */</font> -<font color=#008888>Task::Task</font> (int sub_tasks) - : barrier_ (0) - ,next_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task ctor 0x%x\n</font>", (void *) this)); - if (sub_tasks) - { - next_ = new Task (--sub_tasks); - } -} - -<font color=red>/* - Delete our barrier object and any subtasks we may have. - */</font> -<font color=#008888>Task::~Task</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task dtor 0x%x\n</font>", (void *) this)); - - delete barrier_; - delete next_; -} - -<font color=red>/* - Open our thread pool with the requested number of threads. If subtasks are - enabled, they inherit the thread-pool size. Make sure that the subtasks can - be opened before we open our own threadpool. - */</font> -int <font color=#008888>Task::open</font> (int threads) -{ - if (next_) - { - if (next_->open (threads) == -1) - { - return -1; - } - } - - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} - -<font color=red>/* - Close ourselves and any subtasks. This just prints a message so that we can - assure ourselves things are cleaned up correctly. - */</font> -int <font color=#008888>Task::close</font> (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task close 0x%x\n</font>", (void *) this)); - if (next_) - { - next_->close (flags); - } - - return (0); -} - -<font color=red>/* - Wait for all of the threads in our pool to exit and then wait for any - subtasks. When called from the front of the task chain, this won't return - until all thread pools in the chain have exited. - */</font> -int <font color=#008888>Task::wait</font> (void) -{ - <font color=#008888>inherited::wait</font> (); - if (next_) - { - next_->wait (); - } - return (0); -} - -<font color=red>/* - Like the thread-pools before, this is where all of the work is done. - */</font> -int <font color=#008888>Task::svc</font> (void) -{ - <font color=red>// Wait for all threads to get this far before continuing.</font> - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Task 0x%x starts in thread %u\n</font>", (void *) this, <font color=#008888>ACE_Thread::self</font> ())); - - <font color=red>// getq() wants an ACE_Message_Block so we'll start out with one</font> - <font color=red>// of those. We could do some casting (or even auto-casting) to</font> - <font color=red>// avoid the extra variable but I prefer to be clear about our actions.</font> - ACE_Message_Block *message; - - <font color=red>// What we really put into the queue was our Message_Block.</font> - <font color=red>// After we get the message from the queue, we'll cast it to this </font> - <font color=red>// so that we know how to work on it.</font> - Message_Block *message_block; - - <font color=red>// And, of course, our Message_Block contains our Data_Block</font> - <font color=red>// instead of the typical ACE_Data_Block</font> - Data_Block *data_block; - - <font color=red>// Even though we put Work objects into the queue, we take them</font> - <font color=red>// out using the baseclass pointer. This allows us to create new </font> - <font color=red>// derivatives without having to change this svc() method.</font> - Unit_Of_Work *work; - - while (1) - { - <font color=red>// Get the ACE_Message_Block</font> - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>getq</font>"), -1); - } - - <font color=red>// "<font color=green>Convert</font>" it to our Message_Block</font> - message_block = (Message_Block *) message; - - <font color=red>// Get the ACE_Data_Block and "<font color=green>convert</font>" to Data_Block in one step.</font> - data_block = (Data_Block *) (message_block->data_block ()); - - <font color=red>// Get the unit of work from the data block</font> - work = data_block->data (); - - <font color=red>// Show the object's instance value and "<font color=green>type name</font>"</font> - work->who_am_i (); - work->what_am_i (); - - <font color=red>// If there is a hangup we need to tell our pool-peers as</font> - <font color=red>// well as any subtasks.</font> - if (message_block->msg_type () == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>) - { - <font color=red>// duplicate()ing the message block will increment the</font> - <font color=red>// reference counts on the data blocks. This allows us</font> - <font color=red>// to safely release() the message block. The rule of</font> - <font color=red>// thumb is that if you pass a message block to a new</font> - <font color=red>// owner, duplicate() it. Then you can release() when</font> - <font color=red>// you're done and not worry about memory leaks.</font> - if (this->putq (message_block->duplicate ()) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>putq</font>"), -1); - } - - <font color=red>// If we have a subtask, duplicate() the message block</font> - <font color=red>// again and pass it to that task's queue</font> - if (next_ && next_->putq (message_block->duplicate ()) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>putq</font>"), -1); - } - - <font color=red>// We're now done with our copy of the block, so we can</font> - <font color=red>// release it. Our peers/subtasks have their own message </font> - <font color=red>// block to access the shared data blocks.</font> - message_block->release (); - - break; - } - - <font color=red>// If this isn't a hangup/shutdown message then we tell the</font> - <font color=red>// unit of work to process() for a while.</font> - work->process (); - - if (next_) - { - <font color=red>// If we have subtasks, we pass the block on to them. Notice</font> - <font color=red>// that I don't bother to duplicate() the block since I won't </font> - <font color=red>// release it in this case. I could have invoked</font> - <font color=red>// duplicate() in the puq() and then release()</font> - <font color=red>// afterwards. Either is acceptable.</font> - if (next_->putq (message_block) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>putq</font>"), -1); - } - else - { - <font color=red>// If we don't have subtasks then invoke fini() to tell</font> - <font color=red>// the unit of work that we won't be invoking process()</font> - <font color=red>// any more. Then release() the block. This release()</font> - <font color=red>// would not change if we duplicate()ed in the above conditional</font> - work->fini (); - message_block->release (); - } - - <font color=red>// Pretend that the work takes some time...</font> - <font color=#008888>ACE_OS::sleep</font> (ACE_Time_Value (0, 250)); - } - - return (0); -} -</PRE> -<HR WIDTH="100%"> -<P> -So you see... it wasn't really that much more complicated. We really -just have to remember to pass to <i>next_</i> when we finish working -on the data. If your Unit_Of_Work derivative is going to implement a -state machine be sure that you also implement a fini() method -<em>or</em> ensure that your chain of subtasks is large enough for all -possible states. -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page07.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/013/page07.html b/docs/tutorials/013/page07.html deleted file mode 100644 index 415521d09e3..00000000000 --- a/docs/tutorials/013/page07.html +++ /dev/null @@ -1,255 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -I've been trying to justify the chain of tasks by talking about a -Work object that implements a state machine. The idea is that your -Work object has to perform a series of discrete steps to complete it's -function. Traditionally, all of those steps would take place in one -thread of execution. That thread would probably be one from a Task -thread pool. -<P> -Suppose, however, that some of those steps spend a lot of time waiting -for disk IO. You could find that all of your thread-pool threads -are just sitting there waiting for the disk. You might then be -tempted to increase the thread pool size to get more work through. -However, if some of the stages are memory intensive, you could run out -of memory if all of the workers get to that state at the same time. -<P> -One solution might be to have different thread pools for each state. -Each pool could have it's size tuned appropriately for the work that -would be done there. That's where the chain of Tasks comes in. - In this tutorial's implementation I've taken the -easy route and set all of the thread pools to the same size but a more -realistic solution would be to set each thread pool in the chain to a -specific size as needed by that state of operation. -<P> -There's not much to this header either so I've combined it with the -cpp file as with task. -<P> -<HR WIDTH="100%"> -<PRE> -<HR width=50%><P><center>work.h</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>WORK_H</font> -<font color=blue>#define</font> <font color=purple>WORK_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Log_Msg.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>ace/Synch.h</font>" -<font color=blue>#include</font> "<font color=green>mld.h</font>" - -<font color=red>/* - Our specilized message queue and thread pool will know how to do "<font color=green>work</font>" on - our Unit_Of_Work baseclass. - */</font> -class Unit_Of_Work -{ -public: - Unit_Of_Work (void); - - virtual ~ Unit_Of_Work (void); - - <font color=red>// Display the object instance value</font> - void who_am_i (void); - - <font color=red>// The baseclass can override this to show it's "<font color=green>type name</font>"</font> - virtual void what_am_i (void); - - <font color=red>// This is where you do application level logic. It will be</font> - <font color=red>// called once for each thread pool it passes through. It</font> - <font color=red>// would typically implement a state machine and execute a</font> - <font color=red>// different state on each call.</font> - virtual int process (void); - - <font color=red>// This is called by the last Task in the series (see task.h)</font> - <font color=red>// in case our process() didn't get through all of it's states.</font> - virtual int fini (void); - -protected: - ACE_Atomic_Op < ACE_Mutex, int >state_; - MLD; -}; - -<font color=red>/* - A fairly trivial work derivative that implements an equally trivial state - machine in process() - */</font> -class Work : public Unit_Of_Work -{ -public: - Work (void); - - Work (int message); - - virtual ~ Work (void); - - void what_am_i (void); - - int process (void); - - int fini (void); - -protected: - int message_; - MLD; -}; - -<font color=blue>#endif</font> -</PRE> -<PRE> -<HR width=50%><P><center>work.cpp</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>work.h</font>" - -<font color=red>/* - Initialize the state to zero - */</font> -<font color=#008888>Unit_Of_Work::Unit_Of_Work</font> (void) - : state_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Unit_Of_Work ctor\n</font>", (void *) this)); -} - -<font color=#008888>Unit_Of_Work::~Unit_Of_Work</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Unit_Of_Work dtor\n</font>", (void *) this)); -} - -<font color=red>/* - Display our instance value - */</font> -void <font color=#008888>Unit_Of_Work::who_am_i</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Unit_Of_Work instance\n</font>", (void *) this)); -} - -<font color=red>/* - Dispay our type name - */</font> -void <font color=#008888>Unit_Of_Work::what_am_i</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x I am a Unit_Of_Work object\n</font>", (void *) this)); -} - -<font color=red>/* - Return failure. You should always derive from Unit_Of_Work... - */</font> -int <font color=#008888>Unit_Of_Work::process</font> (void) -{ - return -1; -} - -<font color=red>/* - ditto - */</font> -int <font color=#008888>Unit_Of_Work::fini</font> (void) -{ - return -1; -} - -<font color=red>/* - Default constructor has no "<font color=green>message number</font>" - */</font> -<font color=#008888>Work::Work</font> (void) - :message_ (-1) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Work ctor\n</font>", (void *) this)); -} - -<font color=red>/* - The useful constructor remembers which message it is and will tell you if - you ask. - */</font> -<font color=#008888>Work::Work</font> (int message) - : message_ (message) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Work ctor for message %d\n</font>", (void *) this, message_)); -} - -<font color=#008888>Work::~Work</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Work dtor\n</font>", (void *) this)); -} - -<font color=red>/* - This objects type name is different from the baseclass - */</font> -void <font color=#008888>Work::what_am_i</font> (void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x I am a Work object for message %d\n</font>", (void *) this, message_)); -} - -<font color=red>/* - A very simple state machine that just walks through three stages. If it is - called more than that, it will tell you not to bother. - */</font> -int <font color=#008888>Work::process</font> (void) -{ - switch (++state_) - { - case 1: - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Stage One\n</font>", (void *) this)); - break; - case 2: - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Stage Two\n</font>", (void *) this)); - break; - case 3: - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x Stage Three\n</font>", (void *) this)); - break; - default: - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) 0x%x No work to do in state %d\n</font>", - (void *) this, state_.value ())); - break; - } - return (0); -} - -<font color=red>/* - If you don't have enough subtasks in the chain then the state machine won't - progress to the end. The fini() hook will allow us to recover from that by - executing the remaining states in the final task of the chain. - */</font> -int <font color=#008888>Work::fini</font> (void) -{ - while (state_.value () < 3) - { - if (this->process () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>process</font>"), -1); - } - } - return (0); -} -</PRE> -<HR> -<P> -And that is that. For a more complex machine that may want to "jump -states" you would have to set some "state information" (sorry, bad -choice of terminology again) so that process() could decide what to do -at each call. You might also modify Task::svc() so that it will -respect the return value of process() and do something useful with the -information. -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page08.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/013/page08.html b/docs/tutorials/013/page08.html deleted file mode 100644 index a2780b54482..00000000000 --- a/docs/tutorials/013/page08.html +++ /dev/null @@ -1,41 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 013</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 013</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Multiple thread pools</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> -<P> -And that's the end of another tutorial. This one is probably the most -complicated so far because I've introduced or expanded upon -a number of different -concepts. Namely: state machines, reference counting and task -chaining. I hope I didn't complicate things to the point where the -lesson got lost in the noise. As always, feel free to drop a note to -the ACE-Users mailing list if you feel that some of this could use a -little more explaination. - -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="block.cpp">block.cpp</A> -<LI><A HREF="block.h">block.h</A> -<LI><A HREF="message_queue.cpp">message_queue.cpp</A> -<LI><A HREF="mld.cpp">mld.cpp</A> -<LI><A HREF="mld.h">mld.h</A> -<LI><A HREF="task.cpp">task.cpp</A> -<LI><A HREF="task.h">task.h</A> -<LI><A HREF="work.cpp">work.cpp</A> -<LI><A HREF="work.h">work.h</A> -</UL> -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/013/task.cpp b/docs/tutorials/013/task.cpp deleted file mode 100644 index 6d6bf88b8cc..00000000000 --- a/docs/tutorials/013/task.cpp +++ /dev/null @@ -1,193 +0,0 @@ - -// $Id$ - -#include "task.h" -#include "block.h" -#include "work.h" - -/* - Construct the Task with zero or more subtasks. If subtasks are requested, - we assign our next_ pointer to the first of those and let it worry about - any remaining subtasks. - */ -Task::Task (int sub_tasks) - : barrier_ (0) - ,next_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task ctor 0x%x\n", (void *) this)); - if (sub_tasks) - { - next_ = new Task (--sub_tasks); - } -} - -/* - Delete our barrier object and any subtasks we may have. - */ -Task::~Task (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task dtor 0x%x\n", (void *) this)); - - delete barrier_; - delete next_; -} - -/* - Open our thread pool with the requested number of threads. If subtasks are - enabled, they inherit the thread-pool size. Make sure that the subtasks can - be opened before we open our own threadpool. - */ -int Task::open (int threads) -{ - if (next_) - { - if (next_->open (threads) == -1) - { - return -1; - } - } - - barrier_ = new ACE_Barrier (threads); - return this->activate (THR_NEW_LWP, threads); -} - -/* - Close ourselves and any subtasks. This just prints a message so that we can - assure ourselves things are cleaned up correctly. - */ -int Task::close (u_long flags) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task close 0x%x\n", (void *) this)); - if (next_) - { - next_->close (flags); - } - - return (0); -} - -/* - Wait for all of the threads in our pool to exit and then wait for any - subtasks. When called from the front of the task chain, this won't return - until all thread pools in the chain have exited. - */ -int Task::wait (void) -{ - inherited::wait (); - if (next_) - { - next_->wait (); - } - return (0); -} - -/* - Like the thread-pools before, this is where all of the work is done. - */ -int Task::svc (void) -{ - // Wait for all threads to get this far before continuing. - this->barrier_->wait (); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Task 0x%x starts in thread %u\n", (void *) this, ACE_Thread::self ())); - - // getq() wants an ACE_Message_Block so we'll start out with one - // of those. We could do some casting (or even auto-casting) to - // avoid the extra variable but I prefer to be clear about our actions. - ACE_Message_Block *message; - - // What we really put into the queue was our Message_Block. - // After we get the message from the queue, we'll cast it to this - // so that we know how to work on it. - Message_Block *message_block; - - // And, of course, our Message_Block contains our Data_Block - // instead of the typical ACE_Data_Block - Data_Block *data_block; - - // Even though we put Work objects into the queue, we take them - // out using the baseclass pointer. This allows us to create new - // derivatives without having to change this svc() method. - Unit_Of_Work *work; - - while (1) - { - // Get the ACE_Message_Block - if (this->getq (message) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getq"), -1); - } - - // "Convert" it to our Message_Block - message_block = (Message_Block *) message; - - // Get the ACE_Data_Block and "convert" to Data_Block in one step. - data_block = (Data_Block *) (message_block->data_block ()); - - // Get the unit of work from the data block - work = data_block->data (); - - // Show the object's instance value and "type name" - work->who_am_i (); - work->what_am_i (); - - // If there is a hangup we need to tell our pool-peers as - // well as any subtasks. - if (message_block->msg_type () == ACE_Message_Block::MB_HANGUP) - { - // duplicate()ing the message block will increment the - // reference counts on the data blocks. This allows us - // to safely release() the message block. The rule of - // thumb is that if you pass a message block to a new - // owner, duplicate() it. Then you can release() when - // you're done and not worry about memory leaks. - if (this->putq (message_block->duplicate ()) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putq"), -1); - } - - // If we have a subtask, duplicate() the message block - // again and pass it to that task's queue - if (next_ && next_->putq (message_block->duplicate ()) == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putq"), -1); - } - - // We're now done with our copy of the block, so we can - // release it. Our peers/subtasks have their own message - // block to access the shared data blocks. - message_block->release (); - - break; - } - - // If this isn't a hangup/shutdown message then we tell the - // unit of work to process() for a while. - work->process (); - - if (next_) - { - // If we have subtasks, we pass the block on to them. Notice - // that I don't bother to duplicate() the block since I won't - // release it in this case. I could have invoked - // duplicate() in the puq() and then release() - // afterwards. Either is acceptable. - if (next_->putq (message_block) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putq"), -1); - } - else - { - // If we don't have subtasks then invoke fini() to tell - // the unit of work that we won't be invoking process() - // any more. Then release() the block. This release() - // would not change if we duplicate()ed in the above conditional - work->fini (); - message_block->release (); - } - - // Pretend that the work takes some time... - ACE_OS::sleep (ACE_Time_Value (0, 250)); - } - - return (0); -} diff --git a/docs/tutorials/013/task.h b/docs/tutorials/013/task.h deleted file mode 100644 index ced1ad15cf9..00000000000 --- a/docs/tutorials/013/task.h +++ /dev/null @@ -1,53 +0,0 @@ - -// $Id$ - -#ifndef TASK_H -#define TASK_H - -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "mld.h" - -/* - This is much like the Task we've used in the past for implementing a thread - pool. This time, however, I've made the Task an element in a singly-linked - list. As the svc() method finishes the process() on a unit of work, it - will enqueue that unit of work to the next_ Task if there is one. If the - Task does not have a next_ Task, it will invoke the unit of work object's - fini() method after invoking process(). - */ -class Task : public ACE_Task < ACE_MT_SYNCH > -{ -public: - - typedef ACE_Task < ACE_MT_SYNCH > inherited; - - // Construct ourselves and an optional number of subtasks - // chained beyond us. - Task (int sub_tasks = 0); - ~Task (void); - - // Open the Task with the proper thread-pool size - int open (int threads = 1); - - // Take Unit_Of_Work objects from the thread pool and invoke - // their process() and/or fini() as appropriate. - int svc (void); - - // Shut down the thread pool and it's associated subtasks - int close (u_long flags = 0); - - // Wait for the pool and subtasks to close - int wait (void); - -protected: - ACE_Barrier * barrier_; - Task *next_; - MLD; -}; - -#endif diff --git a/docs/tutorials/013/work.cpp b/docs/tutorials/013/work.cpp deleted file mode 100644 index 4fc16defb48..00000000000 --- a/docs/tutorials/013/work.cpp +++ /dev/null @@ -1,124 +0,0 @@ - -// $Id$ - -#include "work.h" - -/* - Initialize the state to zero - */ -Unit_Of_Work::Unit_Of_Work (void) - : state_ (0) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Unit_Of_Work ctor\n", (void *) this)); -} - -Unit_Of_Work::~Unit_Of_Work (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Unit_Of_Work dtor\n", (void *) this)); -} - -/* - Display our instance value - */ -void Unit_Of_Work::who_am_i (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Unit_Of_Work instance\n", (void *) this)); -} - -/* - Dispay our type name - */ -void Unit_Of_Work::what_am_i (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x I am a Unit_Of_Work object\n", (void *) this)); -} - -/* - Return failure. You should always derive from Unit_Of_Work... - */ -int Unit_Of_Work::process (void) -{ - return -1; -} - -/* - ditto - */ -int Unit_Of_Work::fini (void) -{ - return -1; -} - -/* - Default constructor has no "message number" - */ -Work::Work (void) - :message_ (-1) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Work ctor\n", (void *) this)); -} - -/* - The useful constructor remembers which message it is and will tell you if - you ask. - */ -Work::Work (int message) - : message_ (message) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Work ctor for message %d\n", (void *) this, message_)); -} - -Work::~Work (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Work dtor\n", (void *) this)); -} - -/* - This objects type name is different from the baseclass - */ -void Work::what_am_i (void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x I am a Work object for message %d\n", (void *) this, message_)); -} - -/* - A very simple state machine that just walks through three stages. If it is - called more than that, it will tell you not to bother. - */ -int Work::process (void) -{ - switch (++state_) - { - case 1: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Stage One\n", (void *) this)); - break; - case 2: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Stage Two\n", (void *) this)); - break; - case 3: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x Stage Three\n", (void *) this)); - break; - default: - ACE_DEBUG ((LM_DEBUG, "(%P|%t) 0x%x No work to do in state %d\n", - (void *) this, state_.value ())); - break; - } - return (0); -} - -/* - If you don't have enough subtasks in the chain then the state machine won't - progress to the end. The fini() hook will allow us to recover from that by - executing the remaining states in the final task of the chain. - */ -int Work::fini (void) -{ - while (state_.value () < 3) - { - if (this->process () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "process"), -1); - } - } - return (0); -} diff --git a/docs/tutorials/013/work.h b/docs/tutorials/013/work.h deleted file mode 100644 index bdd0835e098..00000000000 --- a/docs/tutorials/013/work.h +++ /dev/null @@ -1,72 +0,0 @@ - -// $Id$ - -#ifndef WORK_H -#define WORK_H - -#include "ace/Log_Msg.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Synch.h" -#include "mld.h" - -/* - Our specilized message queue and thread pool will know how to do "work" on - our Unit_Of_Work baseclass. - */ -class Unit_Of_Work -{ -public: - Unit_Of_Work (void); - - virtual ~ Unit_Of_Work (void); - - // Display the object instance value - void who_am_i (void); - - // The baseclass can override this to show it's "type name" - virtual void what_am_i (void); - - // This is where you do application level logic. It will be - // called once for each thread pool it passes through. It - // would typically implement a state machine and execute a - // different state on each call. - virtual int process (void); - - // This is called by the last Task in the series (see task.h) - // in case our process() didn't get through all of it's states. - virtual int fini (void); - -protected: - ACE_Atomic_Op < ACE_Mutex, int >state_; - MLD; -}; - -/* - A fairly trivial work derivative that implements an equally trivial state - machine in process() - */ -class Work : public Unit_Of_Work -{ -public: - Work (void); - - Work (int message); - - virtual ~ Work (void); - - void what_am_i (void); - - int process (void); - - int fini (void); - -protected: - int message_; - MLD; -}; - -#endif diff --git a/docs/tutorials/014/014.dsp b/docs/tutorials/014/014.dsp deleted file mode 100644 index 0801d52285f..00000000000 --- a/docs/tutorials/014/014.dsp +++ /dev/null @@ -1,112 +0,0 @@ -# Microsoft Developer Studio Project File - Name="014" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=014 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "014.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "014.mak" CFG="014 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "014 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "014 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "014 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "014 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"stream.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "014 - Win32 Release"
-# Name "014 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\stream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Task.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\EndTask.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Task.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/014/EndTask.h b/docs/tutorials/014/EndTask.h deleted file mode 100644 index 6f89a955817..00000000000 --- a/docs/tutorials/014/EndTask.h +++ /dev/null @@ -1,80 +0,0 @@ - -// $Id$ - -// EndTask.h -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) -// -// - -#ifndef ENDTASK_H -#define ENDTASK_H - -#include "Task.h" - -// When you setup a Stream and push your modules on, -// there are two additional modules that go unseen -// by the user. -// -// The Stream pushes on a Stream_Head in front of -// your first module, and a Stream_Tail behind your -// last module. -// -// If your put() a message to the Stream Tail, it -// assumes you did so in error. This simple EndTask -// class allows you to push a message to it and just -// have it safely Go Away. -// -// All this Task does is release the Message_Block -// and return 0. It's a suitable black-hole. - - -class EndTask : public Task -{ - -public: - - typedef Task inherited; - - EndTask(const char *nameOfTask) : - inherited(nameOfTask, 0) { - - // when we get open()'d, it with 0 threads - // since there is actually no processing to do. - - ACE_DEBUG ((LM_INFO,"(%P|%t) Line: %d, File: %s\n",__LINE__,__FILE__)); - }; - - virtual int open(void *) - { - ACE_DEBUG ((LM_INFO,"(%P|%t) Line: %d, File: %s\n",__LINE__,__FILE__)); - return 0; - } - - virtual int open(void) - { - ACE_DEBUG ((LM_INFO,"(%P|%t) Line: %d, File: %s\n",__LINE__,__FILE__)); - return 0; - } - - virtual ~EndTask(void) { - }; - - virtual int put(ACE_Message_Block *message, - ACE_Time_Value *timeout) { - - ACE_DEBUG ((LM_INFO,"(%P|%t) Line: %d, File: %s\n",__LINE__,__FILE__)); - ACE_UNUSED_ARG(timeout); - - // we don't have anything to do, so - // release() the message. - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s EndTask::put() -- releasing Message_Block\n", this->nameOfTask())); - message->release(); - return 0; - }; - -}; - -#endif // ENDTASK_H diff --git a/docs/tutorials/014/Makefile b/docs/tutorials/014/Makefile deleted file mode 100644 index 42e20ef079f..00000000000 --- a/docs/tutorials/014/Makefile +++ /dev/null @@ -1,74 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = stream - -FILES = Task - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre > combine.shar && rm -f hdr bodies *.pre - -UNSHAR : # - sh combine.shar - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/014/Task.cpp b/docs/tutorials/014/Task.cpp deleted file mode 100644 index 51b4e540be5..00000000000 --- a/docs/tutorials/014/Task.cpp +++ /dev/null @@ -1,210 +0,0 @@ - -// $Id$ - -// Task.cxx -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) -// -// - -#include <ace/Message_Block.h> - -#include "Task.h" - -Task::Task(const char * nameOfTask, - int numberOfThreads) - : d_numberOfThreads(numberOfThreads), - d_barrier(numberOfThreads) -{ - // Just initialize our name, number of threads, and barrier. - - ACE_OS::strcpy(d_nameOfTask, nameOfTask); -} - -Task::~Task(void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::~Task() -- once per Task\n", d_nameOfTask)); -} - -int Task::open(void *arg) -{ - ACE_UNUSED_ARG(arg); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::open() -- once per Task\n", d_nameOfTask)); - - // call ACE_Task::activate() to spawn the threads using - // our Task::svc() as the function to be run. - - // FMM -- Frequently Made Mistake -- - // - // If you specify the flag THR_DETACHED when activating the - // Task, you will get an assert() violation during close(), - // since the Task waits for all of its threads to rejoin. - // - - return this->activate(THR_NEW_LWP, d_numberOfThreads); -} - -int Task::put(ACE_Message_Block *message, - ACE_Time_Value *timeout) -{ - // ACE_Stream uses the put() method of Tasks to send messages. - // This defaultly does nothing. Here we link our put() method - // directly to our putq() method, so that Messages put() to us - // will appear in the Message_Queue that is checked by the - // service threads. - - return this->putq(message, timeout); -} - -int Task::close(u_long flags) -{ - - // When the Stream closes the Module, the Module then close()'s the Task - // and passing a value of (1) as the flag. - - // When a service thread exits, it calls close() with a value that is not - // (1). - - // We use this fact to tell the difference between closing a service thread, - // and closing the main Task itself. - - if (flags == 1) { - - // The Module has asked to close the main Task. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::close() -- flags == 1 -- once per Task\n", d_nameOfTask)); - - // We create a Message_Block... - - ACE_Message_Block *hangupBlock = new ACE_Message_Block(); - - // And make it of the type MB_HANGUP. - - hangupBlock->msg_type(ACE_Message_Block::MB_HANGUP); - - // We then send this Block into the Message_Queue to be seen by the - // service threads. - - // Once again we duplicate() the Block as send it off... - - if (this->putq(hangupBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::close() putq"), -1); - } - - // ..and we're free to release() our copy of it. - - hangupBlock->release(); - - // Now, all we have to do is wait() for the service threads to all - // exit. This is where using THR_DETACHED in the activate() method - // will come back to haunt you. - - // The Stream waits until this returns before attempting to remove - // the next Module/Task group in the Stream. This allows for an - // orderly shutting down of the Stream. - - return this->wait(); - - - } else { - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::close() -- flags != 1 -- once per servicing thread\n", d_nameOfTask)); - - // This is where we can clean up any mess left over by each service thread. - // In this Task, there is nothing to do. - - } - - return 0; - -} - -int Task::svc(void) -{ - - // This is the function that our service threads run once they are spawned. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- once per servicing thread\n", d_nameOfTask)); - - // First, we wait until all of our peer service threads have arrived - // at this point also. - - d_barrier.wait(); - - ACE_Message_Block *messageBlock; - - while (1) { - - // And now we loop almost infinitely. - - // getq() will block until a Message_Block is available to be read, - // or an error occurs. - - if ( this->getq(messageBlock, 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc() getq"), -1); - } - - if (messageBlock->msg_type() == ACE_Message_Block::MB_HANGUP) { - - // If the Message_Block is of type MB_HANGUP, then we're being asked - // to shut down nicely. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- HANGUP block received\n", d_nameOfTask)); - - // So, we duplicate the Block, and put it back into the Message_Queue, - // in case there are some more peer service threads still running. - - if (this->putq(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc() putq"), -1); - } - - // We release our copy of the Block. - messageBlock->release(); - - // And we break out of the nearly infinitely loop, and - // head towards close() ourselves. - break; - } - - // If we're here, then we've received a Message_Block that was - // not informing us to quit, so we're assuming it's a valid - // meaningful Block. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- Normal block received\n", d_nameOfTask)); - - // We grab the read-pointer from the Block, and display it through a DEBUG statement. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- %s\n", d_nameOfTask, messageBlock->rd_ptr() )); - - // We pretend that this takes to time to process the Block. - // If you're on a fast machine, you might have to raise this - // value to actually witness different threads handling - // blocks for each Task. - - ACE_OS::sleep (ACE_Time_Value (0, 250)); - - // Since we're part of a Stream, we duplicate the Block, and - // send it on to the next Task. - - if (put_next(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc() put_next"), -1); - } - - // And then we release our copy of it. - - messageBlock->release(); - - } - - return 0; - -} - - -const char * Task::nameOfTask(void) const -{ - return d_nameOfTask; -} diff --git a/docs/tutorials/014/Task.h b/docs/tutorials/014/Task.h deleted file mode 100644 index adb533c01ef..00000000000 --- a/docs/tutorials/014/Task.h +++ /dev/null @@ -1,68 +0,0 @@ - -// $Id$ - -// Task.h -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) -// -// - -#ifndef TASK_H -#define TASK_H - -#include <ace/Task.h> -#include <ace/Synch.h> - -// Always typedef when possible. - -typedef ACE_Task<ACE_MT_SYNCH> Task_Base; - -class Task : public Task_Base -{ - -public: - - typedef Task_Base inherited; - // This is just good form. - - Task(const char *nameOfTask, - int numberOfThreads); - // Initialize our Task with a name, - // and number of threads to spawn. - - virtual ~Task(void); - - virtual int open(void *arg); - // This is provided to prevent compiler complaints - // about hidden virtual functions. - - virtual int close(u_long flags); - // This closes down the Task and all service threads. - - virtual int put(ACE_Message_Block *message, - ACE_Time_Value *timeout); - // This is the interface that ACE_Stream uses to - // communicate with our Task. - - virtual int svc(void); - // This is the actual service loop each of the service - // threads iterates through. - - const char *nameOfTask(void) const; - // Returns the name of this Task. - -private: - - int d_numberOfThreads; - char d_nameOfTask[64]; - - ACE_Barrier d_barrier; - // Simple Barrier to make sure all of our service - // threads have entered their loop before accepting - // any messages. -}; - - -#endif // TASK_H diff --git a/docs/tutorials/014/combine.shar b/docs/tutorials/014/combine.shar deleted file mode 100644 index c4af4862e35..00000000000 --- a/docs/tutorials/014/combine.shar +++ /dev/null @@ -1,323 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-10-20 19:37 EDT by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/014'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 414 -rw-r--r-- hdr -# 44 -rw-r--r-- bodies -# 1023 -rw-r--r-- page01.pre -# 231 -rw-r--r-- page02.pre -# 651 -rw-r--r-- page03.pre -# 439 -rw-r--r-- page04.pre -# 1079 -rw-r--r-- page05.pre -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh14739; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="Bob McWhirter"> -X <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'hdr' && - chmod 0644 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -25304aa689283dcbed9531b68e7ae2b9 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 414 -eq "$shar_count" || - $echo 'hdr:' 'original size' '414,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -Task.h -Task.cpp -EndTask.h -stream.cpp -SHAR_EOF - $shar_touch -am 1020193698 'bodies' && - chmod 0644 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -43305b4b15975a1e4cbd99b6d3592c12 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 44 -eq "$shar_count" || - $echo 'bodies:' 'original size' '44,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X -<p><b>ACE_Stream</b> is handy when you have several <b>ACE_Task</b> objects -that you would like to link together. -X -<p>An intermediate class you we will deal with is the <b>ACE_Module</b>. -X -<p>The basic plan is to wrap your <b>Task</b> into a <b>Module</b>, push -the <b>Module</b> onto the <b>Stream</b>. Do this for each <b>Task</b>, -X and then inject <b>Message_Block</b>s into the <b>Stream</b>. -X -<p>Each <b>Task</b> then processes the <b>Message_Block</b>, and forwards -it on to the next <b>Task</b> in the <b>Stream</b>. -X -<p>If you are not already familiar with <b>Message_Block</b>s and <b>Message_Queue</b>s, -I highly suggest that you check out <A HREF="../#MQ">Tutorials 10-13</A>. -X -<p>Streams can be used for both downstream and upstream movement of messages. Used -this way mirrors closely the way System V STREAMS work. But you don't have to use them -bidirectionally. In this tutorial, we only use one direction of the Stream. Down. -X -<p>This tutorial is contributed by Bob McWhirter (bob@netwrench.com) -<P> -SHAR_EOF - $shar_touch -am 1012190598 'page01.pre' && - chmod 0644 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -5b2cf5b57c135827e8465cdcfc83357f page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 1023 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '1023,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -<P> -You find pretty soon that anytime you work with ACE_Task<> you -X have to create a derivative. The Task.h header simply provides -X that derivative with the overrides we'll need in our application. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page02.pre' && - chmod 0644 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -4568ed757f3dbc1cebb7dc10d4768894 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 231 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '231,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -<P> -Before we get to main() let's take a look at the Task implementation. -X While we've overridden several methods, the real work is done in -X the close() and svc() methods. -<P> -Notice how close() figures out if it is being called by the shutdown -X of the ACE_Stream or by the exit of svc(). The magic here is -X provided by the <i>flags</i> parameter. By handling the stream -X shutdown in this way, we don't have to do anything strange in -X svc(). We also don't end up with extra hangup messages in the -X queue when the dust all settles down. -<P> -Like our other tutorials, svc() looks for a hangup and processes data. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page03.pre' && - chmod 0644 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -5c35812c1251ef1e8214fa9d9a18d496 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 651 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '651,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -<P> -As stated in the comments below, the default action of the task at the -X stream tail is to treat any received data as an error. In our -X implementation it will often happen that data gets through to -X the tail. How, then, do we handle this without creating an -X error condition? Simple: Create a custom Task for use as the -X stream tail that doesn't consider it an error to receive data. -<P> -Read on... -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page04.pre' && - chmod 0644 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -c6eaa0dbd1216734dcf83f5283d433f3 page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 439 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '439,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -<P> -Now we come to main(). In the previous task-chain tutorial -X every thread pool had to have the same number of threads. This -X time around, we leverage the construction method of ACE_Stream -X and ACE_Module to customize the thread-pool size in each -X ACE_Task of the stream. -<P> -Remember EndTask from the previous page? We create one here and push -X it into the stream to take care of cleaning up the messages. -X Technically, we could have replaced the default Tail task -X created by the ACE framework but it seems to make more sense to -X just push our "tail" onto the stream like the other tasks. The -X caveat to this method is that you must be sure you don't push() -X any other Modules behind the EndTask! -<P> -Once the stream of modules containing tasks is all setup then we can -X put() some data into the stream for processing. The clever use -X of Task::close() makes shutting downt the stream easier than -X ever. No messing with hangup messages at the application level, -X just close() when you're done! What could be simpler? -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page05.pre' && - chmod 0644 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -e1c3ef1d521db6daf9e432fb5582607d page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 1079 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '1079,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh14739 -exit 0 diff --git a/docs/tutorials/014/page01.html b/docs/tutorials/014/page01.html deleted file mode 100644 index d74e678e8cc..00000000000 --- a/docs/tutorials/014/page01.html +++ /dev/null @@ -1,38 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - -<p><b>ACE_Stream</b> is handy when you have several <b>ACE_Task</b> objects -that you would like to link together. - -<p>An intermediate class you we will deal with is the <b>ACE_Module</b>. - -<p>The basic plan is to wrap your <b>Task</b> into a <b>Module</b>, push -the <b>Module</b> onto the <b>Stream</b>. Do this for each <b>Task</b>, - and then inject <b>Message_Block</b>s into the <b>Stream</b>. - -<p>Each <b>Task</b> then processes the <b>Message_Block</b>, and forwards -it on to the next <b>Task</b> in the <b>Stream</b>. - -<p>If you are not already familiar with <b>Message_Block</b>s and <b>Message_Queue</b>s, -I highly suggest that you check out <A HREF="../#MQ">Tutorials 10-13</A>. - -<p>Streams can be used for both downstream and upstream movement of messages. Used -this way mirrors closely the way System V STREAMS work. But you don't have to use them -bidirectionally. In this tutorial, we only use one direction of the Stream. Down. - -<p>This tutorial is contributed by Bob McWhirter (bob@netwrench.com) -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/014/page02.html b/docs/tutorials/014/page02.html deleted file mode 100644 index 452f18f49df..00000000000 --- a/docs/tutorials/014/page02.html +++ /dev/null @@ -1,92 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -You find pretty soon that anytime you work with ACE_Task<> you - have to create a derivative. The Task.h header simply provides - that derivative with the overrides we'll need in our application. -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// Task.h</font> -<font color=red>//</font> -<font color=red>// Tutorial regarding a way to use ACE_Stream.</font> -<font color=red>//</font> -<font color=red>// written by bob mcwhirter (bob@netwrench.com)</font> -<font color=red>//</font> -<font color=red>//</font> - -<font color=blue>#ifndef</font> <font color=purple>TASK_H</font> -<font color=blue>#define</font> <font color=purple>TASK_H</font> - -<font color=blue>#include</font> <ace/Task.h> -<font color=blue>#include</font> <ace/Synch.h> - -<font color=red>// Always typedef when possible.</font> - -typedef ACE_Task<ACE_MT_SYNCH> Task_Base; - -class Task : public Task_Base -{ - -public: - - typedef Task_Base inherited; - <font color=red>// This is just good form.</font> - - Task(const char *nameOfTask, - int numberOfThreads); - <font color=red>// Initialize our Task with a name,</font> - <font color=red>// and number of threads to spawn.</font> - - virtual ~Task(void); - - virtual int open(void *arg); - <font color=red>// This is provided to prevent compiler complaints</font> - <font color=red>// about hidden virtual functions.</font> - - virtual int close(u_long flags); - <font color=red>// This closes down the Task and all service threads.</font> - - virtual int put(ACE_Message_Block *message, - ACE_Time_Value *timeout); - <font color=red>// This is the interface that ACE_Stream uses to</font> - <font color=red>// communicate with our Task.</font> - - virtual int svc(void); - <font color=red>// This is the actual service loop each of the service</font> - <font color=red>// threads iterates through.</font> - - const char *nameOfTask(void) const; - <font color=red>// Returns the name of this Task.</font> - -private: - - int d_numberOfThreads; - char d_nameOfTask[64]; - - ACE_Barrier d_barrier; - <font color=red>// Simple Barrier to make sure all of our service</font> - <font color=red>// threads have entered their loop before accepting</font> - <font color=red>// any messages.</font> -}; - - -<font color=blue>#endif</font> <font color=red>// TASK_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/014/page03.html b/docs/tutorials/014/page03.html deleted file mode 100644 index 114179dd170..00000000000 --- a/docs/tutorials/014/page03.html +++ /dev/null @@ -1,243 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -Before we get to main() let's take a look at the Task implementation. - While we've overridden several methods, the real work is done in - the close() and svc() methods. -<P> -Notice how close() figures out if it is being called by the shutdown - of the ACE_Stream or by the exit of svc(). The magic here is - provided by the <i>flags</i> parameter. By handling the stream - shutdown in this way, we don't have to do anything strange in - svc(). We also don't end up with extra hangup messages in the - queue when the dust all settles down. -<P> -Like our other tutorials, svc() looks for a hangup and processes data. -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// Task.cxx</font> -<font color=red>//</font> -<font color=red>// Tutorial regarding a way to use ACE_Stream.</font> -<font color=red>//</font> -<font color=red>// written by bob mcwhirter (bob@netwrench.com)</font> -<font color=red>//</font> -<font color=red>//</font> - -<font color=blue>#include</font> <ace/Message_Block.h> - -<font color=blue>#include</font> "<font color=green>Task.h</font>" - -<font color=#008888>Task::Task</font>(const char * nameOfTask, - int numberOfThreads) - : d_numberOfThreads(numberOfThreads), - d_barrier(numberOfThreads) -{ - <font color=red>// Just initialize our name, number of threads, and barrier.</font> - - <font color=#008888>ACE_OS::strcpy</font>(d_nameOfTask, nameOfTask); -} - -<font color=#008888>Task::~Task</font>(void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::~Task</font>() -- once per Task\n</font>", d_nameOfTask)); -} - -int <font color=#008888>Task::open</font>(void *arg) -{ - ACE_UNUSED_ARG(arg); - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::open</font>() -- once per Task\n</font>", d_nameOfTask)); - - <font color=red>// call <font color=#008888>ACE_Task::activate</font>() to spawn the threads using</font> - <font color=red>// our <font color=#008888>Task::svc</font>() as the function to be run.</font> - - <font color=red>// FMM -- Frequently Made Mistake --</font> - <font color=red>// </font> - <font color=red>// If you specify the flag THR_DETACHED when activating the</font> - <font color=red>// Task, you will get an assert() violation during close(),</font> - <font color=red>// since the Task waits for all of its threads to rejoin.</font> - <font color=red>// </font> - - return this->activate(THR_NEW_LWP, d_numberOfThreads); -} - -int <font color=#008888>Task::put</font>(ACE_Message_Block *message, - ACE_Time_Value *timeout) -{ - <font color=red>// ACE_Stream uses the put() method of Tasks to send messages.</font> - <font color=red>// This defaultly does nothing. Here we link our put() method</font> - <font color=red>// directly to our putq() method, so that Messages put() to us</font> - <font color=red>// will appear in the Message_Queue that is checked by the</font> - <font color=red>// service threads.</font> - - return this->putq(message, timeout); -} - -int <font color=#008888>Task::close</font>(u_long flags) -{ - - <font color=red>// When the Stream closes the Module, the Module then close()'s the Task</font> - <font color=red>// and passing a value of (1) as the flag.</font> - - <font color=red>// When a service thread exits, it calls close() with a value that is not</font> - <font color=red>// (1).</font> - - <font color=red>// We use this fact to tell the difference between closing a service thread,</font> - <font color=red>// and closing the main Task itself.</font> - - if (flags == 1) { - - <font color=red>// The Module has asked to close the main Task.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::close</font>() -- flags == 1 -- once per Task\n</font>", d_nameOfTask)); - - <font color=red>// We create a Message_Block...</font> - - ACE_Message_Block *hangupBlock = new ACE_Message_Block(); - - <font color=red>// And make it of the type MB_HANGUP. </font> - - hangupBlock->msg_type(<font color=#008888>ACE_Message_Block::MB_HANGUP</font>); - - <font color=red>// We then send this Block into the Message_Queue to be seen by the </font> - <font color=red>// service threads.</font> - - <font color=red>// Once again we duplicate() the Block as send it off...</font> - - if (this->putq(hangupBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::close</font>() putq</font>"), -1); - } - - <font color=red>// ..and we're free to release() our copy of it.</font> - - hangupBlock->release(); - - <font color=red>// Now, all we have to do is wait() for the service threads to all </font> - <font color=red>// exit. This is where using THR_DETACHED in the activate() method</font> - <font color=red>// will come back to haunt you.</font> - - <font color=red>// The Stream waits until this returns before attempting to remove</font> - <font color=red>// the next Module/Task group in the Stream. This allows for an</font> - <font color=red>// orderly shutting down of the Stream.</font> - - return this->wait(); - - - } else { - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::close</font>() -- flags != 1 -- once per servicing thread\n</font>", d_nameOfTask)); - - <font color=red>// This is where we can clean up any mess left over by each service thread.</font> - <font color=red>// In this Task, there is nothing to do.</font> - - } - - return 0; - -} - -int <font color=#008888>Task::svc</font>(void) -{ - - <font color=red>// This is the function that our service threads run once they are spawned.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- once per servicing thread\n</font>", d_nameOfTask)); - - <font color=red>// First, we wait until all of our peer service threads have arrived</font> - <font color=red>// at this point also.</font> - - d_barrier.wait(); - - ACE_Message_Block *messageBlock; - - while (1) { - - <font color=red>// And now we loop almost infinitely.</font> - - <font color=red>// getq() will block until a Message_Block is available to be read,</font> - <font color=red>// or an error occurs.</font> - - if ( this->getq(messageBlock, 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::svc</font>() getq</font>"), -1); - } - - if (messageBlock->msg_type() == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>) { - - <font color=red>// If the Message_Block is of type MB_HANGUP, then we're being asked</font> - <font color=red>// to shut down nicely.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- HANGUP block received\n</font>", d_nameOfTask)); - - <font color=red>// So, we duplicate the Block, and put it back into the Message_Queue,</font> - <font color=red>// in case there are some more peer service threads still running.</font> - - if (this->putq(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::svc</font>() putq</font>"), -1); - } - - <font color=red>// We release our copy of the Block.</font> - messageBlock->release(); - - <font color=red>// And we break out of the nearly infinitely loop, and</font> - <font color=red>// head towards close() ourselves.</font> - break; - } - - <font color=red>// If we're here, then we've received a Message_Block that was </font> - <font color=red>// not informing us to quit, so we're assuming it's a valid</font> - <font color=red>// meaningful Block.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- Normal block received\n</font>", d_nameOfTask)); - - <font color=red>// We grab the read-pointer from the Block, and display it through a DEBUG statement.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- %s\n</font>", d_nameOfTask, messageBlock->rd_ptr() )); - - <font color=red>// We pretend that this takes to time to process the Block.</font> - <font color=red>// If you're on a fast machine, you might have to raise this</font> - <font color=red>// value to actually witness different threads handling</font> - <font color=red>// blocks for each Task.</font> - - <font color=#008888>ACE_OS::sleep</font> (ACE_Time_Value (0, 250)); - - <font color=red>// Since we're part of a Stream, we duplicate the Block, and </font> - <font color=red>// send it on to the next Task.</font> - - if (put_next(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::svc</font>() put_next</font>"), -1); - } - - <font color=red>// And then we release our copy of it.</font> - - messageBlock->release(); - - } - - return 0; - -} - - -const char * <font color=#008888>Task::nameOfTask</font>(void) const -{ - return d_nameOfTask; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/014/page04.html b/docs/tutorials/014/page04.html deleted file mode 100644 index e4ca848ff76..00000000000 --- a/docs/tutorials/014/page04.html +++ /dev/null @@ -1,109 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -As stated in the comments below, the default action of the task at the - stream tail is to treat any received data as an error. In our - implementation it will often happen that data gets through to - the tail. How, then, do we handle this without creating an - error condition? Simple: Create a custom Task for use as the - stream tail that doesn't consider it an error to receive data. -<P> -Read on... -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// EndTask.h</font> -<font color=red>//</font> -<font color=red>// Tutorial regarding a way to use ACE_Stream.</font> -<font color=red>//</font> -<font color=red>// written by bob mcwhirter (bob@netwrench.com)</font> -<font color=red>//</font> -<font color=red>//</font> - -<font color=blue>#ifndef</font> <font color=purple>ENDTASK_H</font> -<font color=blue>#define</font> <font color=purple>ENDTASK_H</font> - -<font color=blue>#include</font> "<font color=green>Task.h</font>" - -<font color=red>// When you setup a Stream and push your modules on,</font> -<font color=red>// there are two additional modules that go unseen</font> -<font color=red>// by the user.</font> -<font color=red>//</font> -<font color=red>// The Stream pushes on a Stream_Head in front of</font> -<font color=red>// your first module, and a Stream_Tail behind your</font> -<font color=red>// last module.</font> -<font color=red>//</font> -<font color=red>// If your put() a message to the Stream Tail, it</font> -<font color=red>// assumes you did so in error. This simple EndTask</font> -<font color=red>// class allows you to push a message to it and just</font> -<font color=red>// have it safely Go Away.</font> -<font color=red>//</font> -<font color=red>// All this Task does is release the Message_Block</font> -<font color=red>// and return 0. It's a suitable black-hole.</font> - - -class EndTask : public Task -{ - -public: - - typedef Task inherited; - - EndTask(const char *nameOfTask) : - inherited(nameOfTask, 0) { - - <font color=red>// when we get open()'d, it with 0 threads</font> - <font color=red>// since there is actually no processing to do.</font> - - cerr << __LINE__ << "<font color=green> </font>" << __FILE__ << endl; - }; - - virtual int open(void *) - { - cerr << __LINE__ << "<font color=green> </font>" << __FILE__ << endl; - return 0; - } - - virtual int open(void) - { - cerr << __LINE__ << "<font color=green> </font>" << __FILE__ << endl; - return 0; - } - - virtual ~EndTask(void) { - }; - - virtual int put(ACE_Message_Block *message, - ACE_Time_Value *timeout) { - - cerr << __LINE__ << "<font color=green> </font>" << __FILE__ << endl; - ACE_UNUSED_ARG(timeout); - - <font color=red>// we don't have anything to do, so</font> - <font color=red>// release() the message.</font> - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>EndTask::put</font>() -- releasing Message_Block\n</font>", this->nameOfTask())); - message->release(); - return 0; - }; - -}; - -<font color=blue>#endif</font> <font color=red>// ENDTASK_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/014/page05.html b/docs/tutorials/014/page05.html deleted file mode 100644 index fa5c4fd132e..00000000000 --- a/docs/tutorials/014/page05.html +++ /dev/null @@ -1,215 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -Now we come to main(). In the previous task-chain tutorial - every thread pool had to have the same number of threads. This - time around, we leverage the construction method of ACE_Stream - and ACE_Module to customize the thread-pool size in each - ACE_Task of the stream. -<P> -Remember EndTask from the previous page? We create one here and push - it into the stream to take care of cleaning up the messages. - Technically, we could have replaced the default Tail task - created by the ACE framework but it seems to make more sense to - just push our "tail" onto the stream like the other tasks. The - caveat to this method is that you must be sure you don't push() - any other Modules behind the EndTask! -<P> -Once the stream of modules containing tasks is all setup then we can - put() some data into the stream for processing. The clever use - of Task::close() makes shutting downt the stream easier than - ever. No messing with hangup messages at the application level, - just close() when you're done! What could be simpler? -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// stream.cxx</font> -<font color=red>//</font> -<font color=red>// Tutorial regarding a way to use ACE_Stream.</font> -<font color=red>//</font> -<font color=red>// written by bob mcwhirter (bob@netwrench.com)</font> -<font color=red>//</font> -<font color=red>//</font> - -<font color=blue>#include</font> "<font color=green>Task.h</font>" -<font color=blue>#include</font> "<font color=green>EndTask.h</font>" -<font color=red>// This is our specialized ACE_Task.</font> - -<font color=blue>#include</font> <ace/Module.h> -<font color=blue>#include</font> <ace/Stream.h> -<font color=red>// These are the neccessary ACE headers.</font> - - -typedef ACE_Module<ACE_MT_SYNCH> Module; -typedef ACE_Stream<ACE_MT_SYNCH> Stream; -<font color=red>// Just to avoid a lot of typing, typedefs</font> -<font color=red>// are generally a good idea.</font> - -int main(int argc, char *argv[]) -{ - cerr << __LINE__ << endl; - - int numberOfMessages = argc > 1 ? <font color=#008888>ACE_OS::atoi</font>(argv[1]) : 3; - <font color=red>// unless otherwise specified, just send three messages</font> - <font color=red>// down the stream.</font> - - Stream theStream; - <font color=red>// the ACE_Stream itself.</font> - - cerr << __LINE__ << endl; - - <font color=red>// Now, we instantiate 4 different Tasks. These do not</font> - <font color=red>// need to be all the same class, but they do need to</font> - <font color=red>// all derrive from the same flavor of ACE_Task.</font> - <font color=red>//</font> - <font color=red>// Also, we instantiate a fifth end-cap Task to clean</font> - <font color=red>// up Message_Blocks as they reach the end.</font> - - Task *taskOne; - Task *taskTwo; - Task *taskThree; - Task *taskFour; - Task *taskEnd; - - <font color=red>// Out Task's take two arguments: a name, and the number</font> - <font color=red>// of threads to dedicate to the task.</font> - - taskOne = new Task("<font color=green>Task No. 1</font>", 1); - taskTwo = new Task("<font color=green>Task No. 2</font>", 3); - taskThree = new Task("<font color=green>Task No. 3</font>", 7); - taskFour = new Task("<font color=green>Task No. 4</font>", 1); - - <font color=red>// Our EndTask only takes 1 argument, as it actually</font> - <font color=red>// doesn't spawn any threads for processing.</font> - - taskEnd = new EndTask("<font color=green>End Task</font>"); - - Module *moduleOne; - Module *moduleTwo; - Module *moduleThree; - Module *moduleFour; - Module *moduleEnd; - - <font color=red>// ACE_Stream accepts ACE_Modules, which are simply a pair of</font> - <font color=red>// ACE_Tasks. One is dedicated for writing, while the other</font> - <font color=red>// is dedicated to reading. Think of the writing side as</font> - <font color=red>// downstream, and the reading side as upstream.</font> - <font color=red>//</font> - <font color=red>// We're only working with a unidirection Stream today,</font> - <font color=red>// so we'll only actually install a Task into the write</font> - <font color=red>// side of the module, effectively downstream.</font> - - cerr << __LINE__ << endl; - moduleOne = new Module("<font color=green>Module No. 1</font>", taskOne); - moduleTwo = new Module("<font color=green>Module No. 2</font>", taskTwo); - moduleThree = new Module("<font color=green>Module No. 3</font>", taskThree); - moduleFour = new Module("<font color=green>Module No. 4</font>", taskFour); - moduleEnd = new Module("<font color=green>Module End</font>", taskEnd); - - cerr << __LINE__ << endl; - <font color=red>// Now we push the Modules onto the Stream.</font> - <font color=red>// Pushing adds the module to the head, or </font> - <font color=red>// otherwise prepends it to whatever modules</font> - <font color=red>// are already installed.</font> - - <font color=red>// So, you need to push() the modules on -backwards-</font> - <font color=red>// from our viewpoint.</font> - - if (theStream.push(moduleEnd) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - cerr << __LINE__ << endl; - if (theStream.push(moduleFour) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - <font color=red>// As we push a Module onto the Stream, it gets opened.</font> - <font color=red>// When a Module open()s, it opens the Tasks that it contains.</font> - <font color=red>//</font> - <font color=red>// Since we cannot provide an argument to this embedded</font> - <font color=red>// call to open(), we supplied specified the number of</font> - <font color=red>// threads in the constructor of our Tasks.</font> - - if (theStream.push(moduleThree) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - if (theStream.push(moduleTwo) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - if (theStream.push(moduleOne) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - cerr << __LINE__ << endl; - <font color=red>// Now that the Modules are open, the Tasks threads should</font> - <font color=red>// be launching and entering their svc() loop, so we send</font> - <font color=red>// some messages down the Stream.</font> - - int sent = 1; - - ACE_Message_Block *message; - - while (sent <= numberOfMessages) { - - <font color=red>// First, create ourselves a Message_Block.</font> - <font color=red>// see Tutorials 10-13 for more information</font> - <font color=red>// about Message_Blocks and Message_Queues.</font> - - message = new ACE_Message_Block(128); - - <font color=red>// Now, we grab the write-pointer from the Block,</font> - <font color=red>// and sprintf() our text into it.</font> - - <font color=#008888>ACE_OS::sprintf</font>(message->wr_ptr(), "<font color=green>Message No. %d</font>", sent); - - <font color=red>// All we have to do now is drop the Message_Block</font> - <font color=red>// into the Stream.</font> - - <font color=red>// It is always a good idea to duplicate() a Message_Block</font> - <font color=red>// when you put it into any Message_Queue, as then</font> - <font color=red>// you can always be allowed to release() your copy</font> - <font color=red>// without worry.</font> - - if (theStream.put(message->duplicate(), 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>put</font>"), -1); - } - - message->release(); - ++sent; - } - - <font color=red>// Now that we've sent our Message_Blocks, close down</font> - <font color=red>// the Stream.</font> - <font color=red>//</font> - <font color=red>// The Stream will automagically delete the Modules and</font> - <font color=red>// the contained Tasks. We don't have to do that.</font> - <font color=red>//</font> - <font color=red>// This call will block (due to the way we've written our </font> - <font color=red>// Task class) until all Message_Blocks have cleared the</font> - <font color=red>// entire Stream, and all associated threads have exited.</font> - - theStream.close(); - - return 0; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/014/page06.html b/docs/tutorials/014/page06.html deleted file mode 100644 index 3bbff685aa8..00000000000 --- a/docs/tutorials/014/page06.html +++ /dev/null @@ -1,28 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - -Ok, so that's the Stream tutorial. As you can see, it's much simpler - than the task-chain developed last time but at the same time it - is also much more extensible. - -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="Task.h">Task.h</A> -<LI><A HREF="Task.cpp">Task.cpp</A> -<LI><A HREF="EndTask.h">EndTask.h</A> -<LI><A HREF="stream.cpp">stream.cpp</A> -</UL> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/014/stream.cpp b/docs/tutorials/014/stream.cpp deleted file mode 100644 index f135d6bb3c1..00000000000 --- a/docs/tutorials/014/stream.cpp +++ /dev/null @@ -1,176 +0,0 @@ - -// $Id$ - -// stream.cxx -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) -// -// - -#include "Task.h" -#include "EndTask.h" -// This is our specialized ACE_Task. - -#include <ace/Module.h> -#include <ace/Stream.h> -#include <ace/streams.h> -// These are the neccessary ACE headers. - - -typedef ACE_Module<ACE_MT_SYNCH> Module; -typedef ACE_Stream<ACE_MT_SYNCH> Stream; -// Just to avoid a lot of typing, typedefs -// are generally a good idea. - -int main(int argc, char *argv[]) -{ - cerr << __LINE__ << endl; - - int numberOfMessages = argc > 1 ? ACE_OS::atoi(argv[1]) : 3; - // unless otherwise specified, just send three messages - // down the stream. - - Stream theStream; - // the ACE_Stream itself. - - cerr << __LINE__ << endl; - - // Now, we instantiate 4 different Tasks. These do not - // need to be all the same class, but they do need to - // all derrive from the same flavor of ACE_Task. - // - // Also, we instantiate a fifth end-cap Task to clean - // up Message_Blocks as they reach the end. - - Task *taskOne; - Task *taskTwo; - Task *taskThree; - Task *taskFour; - Task *taskEnd; - - // Out Task's take two arguments: a name, and the number - // of threads to dedicate to the task. - - taskOne = new Task("Task No. 1", 1); - taskTwo = new Task("Task No. 2", 3); - taskThree = new Task("Task No. 3", 7); - taskFour = new Task("Task No. 4", 1); - - // Our EndTask only takes 1 argument, as it actually - // doesn't spawn any threads for processing. - - taskEnd = new EndTask("End Task"); - - Module *moduleOne; - Module *moduleTwo; - Module *moduleThree; - Module *moduleFour; - Module *moduleEnd; - - // ACE_Stream accepts ACE_Modules, which are simply a pair of - // ACE_Tasks. One is dedicated for writing, while the other - // is dedicated to reading. Think of the writing side as - // downstream, and the reading side as upstream. - // - // We're only working with a unidirection Stream today, - // so we'll only actually install a Task into the write - // side of the module, effectively downstream. - - cerr << __LINE__ << endl; - moduleOne = new Module("Module No. 1", taskOne); - moduleTwo = new Module("Module No. 2", taskTwo); - moduleThree = new Module("Module No. 3", taskThree); - moduleFour = new Module("Module No. 4", taskFour); - moduleEnd = new Module("Module End", taskEnd); - - cerr << __LINE__ << endl; - // Now we push the Modules onto the Stream. - // Pushing adds the module to the head, or - // otherwise prepends it to whatever modules - // are already installed. - - // So, you need to push() the modules on -backwards- - // from our viewpoint. - - if (theStream.push(moduleEnd) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - cerr << __LINE__ << endl; - if (theStream.push(moduleFour) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - // As we push a Module onto the Stream, it gets opened. - // When a Module open()s, it opens the Tasks that it contains. - // - // Since we cannot provide an argument to this embedded - // call to open(), we supplied specified the number of - // threads in the constructor of our Tasks. - - if (theStream.push(moduleThree) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - if (theStream.push(moduleTwo) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - if (theStream.push(moduleOne) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - cerr << __LINE__ << endl; - // Now that the Modules are open, the Tasks threads should - // be launching and entering their svc() loop, so we send - // some messages down the Stream. - - int sent = 1; - - ACE_Message_Block *message; - - while (sent <= numberOfMessages) { - - // First, create ourselves a Message_Block. - // see Tutorials 10-13 for more information - // about Message_Blocks and Message_Queues. - - message = new ACE_Message_Block(128); - - // Now, we grab the write-pointer from the Block, - // and sprintf() our text into it. - - ACE_OS::sprintf(message->wr_ptr(), "Message No. %d", sent); - - // All we have to do now is drop the Message_Block - // into the Stream. - - // It is always a good idea to duplicate() a Message_Block - // when you put it into any Message_Queue, as then - // you can always be allowed to release() your copy - // without worry. - - if (theStream.put(message->duplicate(), 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "put"), -1); - } - - message->release(); - ++sent; - } - - // Now that we've sent our Message_Blocks, close down - // the Stream. - // - // The Stream will automagically delete the Modules and - // the contained Tasks. We don't have to do that. - // - // This call will block (due to the way we've written our - // Task class) until all Message_Blocks have cleared the - // entire Stream, and all associated threads have exited. - - theStream.close(); - - return 0; -} diff --git a/docs/tutorials/015/015-client.dsp b/docs/tutorials/015/015-client.dsp deleted file mode 100644 index 5152df92235..00000000000 --- a/docs/tutorials/015/015-client.dsp +++ /dev/null @@ -1,138 +0,0 @@ -# Microsoft Developer Studio Project File - Name="015 client" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=015 client - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "015-client.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "015-client.mak" CFG="015 client - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "015 client - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "015 client - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "015 client - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "015 client - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "015 client - Win32 Release"
-# Name "015 client - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=client.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Client_i.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Compressor.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Crypt.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Protocol_Stream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Protocol_Task.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Recv.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Xmit.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=Client_i.h
-# End Source File
-# Begin Source File
-
-SOURCE=Protocol_Stream.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/015/015-server.dsp b/docs/tutorials/015/015-server.dsp deleted file mode 100644 index d9f45886fe9..00000000000 --- a/docs/tutorials/015/015-server.dsp +++ /dev/null @@ -1,166 +0,0 @@ -# Microsoft Developer Studio Project File - Name="015 server" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=015 server - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "015-server.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "015-server.mak" CFG="015 server - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "015 server - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "015 server - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "015 server - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "015 server - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"../server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "015 server - Win32 Release"
-# Name "015 server - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=Compressor.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Crypt.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Handler.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Protocol_Stream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Protocol_Task.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Recv.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=server.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Server_i.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=Xmit.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=Compressor.h
-# End Source File
-# Begin Source File
-
-SOURCE=Crypt.h
-# End Source File
-# Begin Source File
-
-SOURCE=Handler.h
-# End Source File
-# Begin Source File
-
-SOURCE=Protocol_Stream.h
-# End Source File
-# Begin Source File
-
-SOURCE=Protocol_Task.h
-# End Source File
-# Begin Source File
-
-SOURCE=Recv.h
-# End Source File
-# Begin Source File
-
-SOURCE=Server_i.h
-# End Source File
-# Begin Source File
-
-SOURCE=Xmit.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/015/Client_i.cpp b/docs/tutorials/015/Client_i.cpp deleted file mode 100644 index 6415fed1966..00000000000 --- a/docs/tutorials/015/Client_i.cpp +++ /dev/null @@ -1,60 +0,0 @@ - -// $Id$ - -#include "Client_i.h" -#include "ace/Message_Block.h" -#include "ace/INET_Addr.h" -#include "ace/SOCK_Connector.h" - -// Simple constructor just remembers the endpoint information for use by open. -Client::Client( u_short _port, const char * _server) - : port_(_port), server_(_server) -{ - ; -} - -/* Do nothing. This should probably call close() if we can make sure - that it's OK to close() multiple times. -*/ -Client::~Client(void) -{ - ; -} - -/* Open the connection to the server. This is traditional ACE. We - simply construct an endpoint and use a connector to establish the - link. -*/ -int Client::open( void ) -{ - ACE_INET_Addr addr(port_,server_); - ACE_SOCK_Connector con; - - if( con.connect(peer(),addr) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_SOCK_Connector::connect()"), -1); - } - - // Something new here... We have to use the protocol stream - // to ensure that our data is in the correct format when - // received by the server. Thus, we open the stream and - // transfer ownership of the peer. - return stream().open( peer() ); -} - -// The remainder of the functions just delegate to the stream. - -int Client::close( void ) -{ - return stream().close(); -} - -int Client::put( ACE_Message_Block * _message ) -{ - return stream().put(_message,0); -} - -int Client::get( ACE_Message_Block * & _response ) -{ - return stream().get(_response); -} diff --git a/docs/tutorials/015/Client_i.h b/docs/tutorials/015/Client_i.h deleted file mode 100644 index c9f4e496bf2..00000000000 --- a/docs/tutorials/015/Client_i.h +++ /dev/null @@ -1,74 +0,0 @@ - -// $Id$ - -#ifndef CLIENT_H -#define CLIENT_H - -#include "ace/SOCK_Stream.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "Protocol_Stream.h" - -class ACE_Message_Block; - -/* Hide the details of connection and protocol-conformance from the - application-level logic. -*/ -class Client -{ -public: - // Provide the server information when constructing the - // object. This could (and probably should) be moved to the - // open() method. - Client( u_short _port, const char * _server ); - - // Cleanup... - ~Client(void); - - // Open the connection to the server. - int open(void); - - // Close the connection to the server. Be sure to do this - // before you let the Client go out of scope. - int close(void); - - // Put a message to the server. The Client assumes ownership - // of _message at that point and will release() it when done. - // Do not use _message after passing it to put(). - int put( ACE_Message_Block * _message ); - - // Get a response from the server. The caller becomes the - // owner of _response after this call and is responsible for - // invoking release() when done. - int get( ACE_Message_Block * & _response ); - -private: - // Protocol_Stream hides the protocol conformance details from - // us. - Protocol_Stream stream_; - - // We create a connection on the peer_ and then pass ownership - // of it to the protocol stream. - ACE_SOCK_Stream peer_; - - // Endpoing information saved by the constructor for use by open(). - u_short port_; - const char * server_; - - // Accessors for the complex member variables. - - Protocol_Stream & stream(void) - { - return this->stream_; - } - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } -}; - -#endif // CLIENT_H diff --git a/docs/tutorials/015/Compressor.cpp b/docs/tutorials/015/Compressor.cpp deleted file mode 100644 index f93d44009de..00000000000 --- a/docs/tutorials/015/Compressor.cpp +++ /dev/null @@ -1,96 +0,0 @@ - -// $Id$ - -#include "Compressor.h" -#include "ace/SOCK_Stream.h" - -/* Construct our baseclass with the proper thread count. I really - should remove this option... - */ -Compressor::Compressor( int _thr_count ) - : Protocol_Task(_thr_count) -{ - ; -} - -Compressor::~Compressor(void) -{ - ; -} - -/* This is where you insert your compression code. Most compressors - want to work on a block of data instead of a byte-stream. - Fortunately the message block has a block that can be compressed. - Take a look at libz for a quick way to add compression to your - apps - */ -int Compressor::send(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t) Compressor::send() compressing (%s)\n", message->rd_ptr() )); - - // Create a block to hold the compressed data. I belive libz - // recommends a buffer about 10-20% larger than the source. - // Other libraries/algorithms may have their own quirks. - ACE_Message_Block * compressed = new ACE_Message_Block( message->size() ); - - // Perform a bogus compression algorithm. 'CD' just tells me - // that this is compressed data and when we "decompress" we'll - // look for this signature to validate the data received. - ACE_OS::sprintf( compressed->wr_ptr(), "CD:%s", message->rd_ptr() ); - compressed->wr_ptr( strlen(compressed->wr_ptr())+1 ); - - // Send the compressed data down the stream to the next module - this->put_next( compressed ); - - // We're done here. - message->release(); - - return( 0 ); -} - -/* And here's the decompression side. We've written Xmit/Recv so that - we're guaranteed to get an entire block of compressed data. If - we'd used recv() in the Recv object then we might have gotten a - partial block and that may not decompress very nicely. - */ -int Compressor::recv(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t) Compress::recv() decompressing (%s)\n", message->rd_ptr() )); - - // Room for the decompressed data. In the real world you - // would probably want to send the original (uncompressed) - // data size in the message. You can predict the maximum - // possible decompression size but it's cheap and easy just to - // send that along. Look again at how I do exacly that - // between Xmit and Recv. - ACE_Message_Block * decompressed = new ACE_Message_Block( message->size() ); - - // Check for our signature. Even when you use a real - // compression algorithm you may want to include your own - // signature so that you can verify the block. It pays to be - // paranoid! - if( ACE_OS::strncmp( message->rd_ptr(), "CD:", 3 ) ) - { - ACE_DEBUG ((LM_INFO, "(%P|%t) Improperly encompressed data.\n" )); - message->release(); - return(-1); - } - - // Skip past the signature before going any further. - message->rd_ptr( 3 ); - - // Perform a bogus decompression algorithm. This is where you - // would feed to libz or your favorite decompressor. (It's - // costly but you could invoke popen() on gzip!) - ACE_OS::sprintf( decompressed->wr_ptr(), "%s", message->rd_ptr() ); - decompressed->wr_ptr( strlen(decompressed->wr_ptr())+1 ); - - // Recv the decompressed data down the stream to the next module - this->put_next( decompressed ); - - // We're done here. - message->release(); - - return( 0 ); -} - diff --git a/docs/tutorials/015/Compressor.h b/docs/tutorials/015/Compressor.h deleted file mode 100644 index 4aaa83144ed..00000000000 --- a/docs/tutorials/015/Compressor.h +++ /dev/null @@ -1,43 +0,0 @@ - -// $Id$ - -#ifndef COMPRESSOR_H -#define COMPRESSOR_h - -#include "Protocol_Task.h" - -/* A reallly dumb compression object. (It actually adds 3 bytes to - every message block.) -*/ -class Compressor : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - // I've given you the option of creating this task derivative - // with a number of threads. In retro-spect that really isn't - // a good idea. Most client/server systems rely on requests - // and responses happening in a predicatable order. Introduce - // a thread pool and message queue and that ordering goes - // right out the window. In other words: Don't ever use the - // constructor parameter! - Compressor( int _thr_count = 0 ); - - ~Compressor(void); - -protected: - - // This is called when the compressor is on the downstream - // side. We'll take the message, compress it and move it - // along to the next module. - int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - // This one is called on the upstream side. No surprise: we - // decompress the data and send it on up the stream. - int recv(ACE_Message_Block *message, - ACE_Time_Value *timeout); -}; - -#endif // COMPRESSOR_H diff --git a/docs/tutorials/015/Crypt.cpp b/docs/tutorials/015/Crypt.cpp deleted file mode 100644 index 1967bbe0ff1..00000000000 --- a/docs/tutorials/015/Crypt.cpp +++ /dev/null @@ -1,77 +0,0 @@ - -// $Id$ - -#include "Crypt.h" -#include "ace/SOCK_Stream.h" - -/* The expected constructor... - */ -Crypt::Crypt( int _thr_count ) - : Protocol_Task(_thr_count) -{ -} - -Crypt::~Crypt(void) -{ -} - -/* To send the data we'll apply a signature and encryption. - */ -int Crypt::send(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t) Crypt::send() encrypting (%s)\n", message->rd_ptr() )); - - // I suspect that some encryptors might change the data size. - // It probably isn't safe to create a same-size destination buffer. - ACE_Message_Block * encrypted = new ACE_Message_Block( message->size() ); - - // Perform a bogus encryption algorithm and add our safety - // signature. Adding the original data size is also probably - // a good idea that I haven't encorporated here. - ACE_OS::sprintf( encrypted->wr_ptr(), "ED:%s", message->rd_ptr() ); - encrypted->wr_ptr( strlen(encrypted->wr_ptr())+1 ); - - // Send the encrypted data down the stream to the next module - this->put_next( encrypted ); - - // We're done here. - message->release(); - - return( 0 ); -} - -/* The upstream movement requires that we decrypt what the peer has - given us. -*/ -int Crypt::recv(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t) Crypt::recv() decrypting (%s)\n", message->rd_ptr() )); - - // Create a destination for the decrypted data. The same - // block size caveat exists of course. - ACE_Message_Block * decrypted = new ACE_Message_Block( message->size() ); - - // Check the signature as expected. - if( ACE_OS::strncmp( message->rd_ptr(), "ED:", 3 ) ) - { - ACE_DEBUG ((LM_INFO, "(%P|%t) Improperly encrypted data.\n" )); - message->release(); - return(-1); - } - - // Don't forget to skip past the signature before decrypting - // or things will be quite exciting! - message->rd_ptr( 3 ); - - // Perform a bogus decryption algorithm - ACE_OS::sprintf( decrypted->wr_ptr(), "%s", message->rd_ptr() ); - decrypted->wr_ptr( strlen(decrypted->wr_ptr())+1 ); - - // Send the decrypted data down the stream to the next module - this->put_next( decrypted ); - - // We're done here. - message->release(); - - return( 0 ); -} diff --git a/docs/tutorials/015/Crypt.h b/docs/tutorials/015/Crypt.h deleted file mode 100644 index c7fb1d5948f..00000000000 --- a/docs/tutorials/015/Crypt.h +++ /dev/null @@ -1,35 +0,0 @@ - -// $Id$ - -#ifndef CRYPT_H -#define CRYPT_h - -#include "Protocol_Task.h" - -/* An interface (adaptor) between your favorite encryption method and - an ACE_Stream. -*/ -class Crypt : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - // Again we have the option of multiple threads and again I - // regret tempting folks to use it. - Crypt( int _thr_count = 0 ); - - ~Crypt(void); - -protected: - - // Moving downstream will encrypt the data - int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - // And moving upstream will decrypt it. - int recv(ACE_Message_Block *message, - ACE_Time_Value *timeout); -}; - -#endif // CRYPT_H diff --git a/docs/tutorials/015/Handler.cpp b/docs/tutorials/015/Handler.cpp deleted file mode 100644 index ab141c7e8c2..00000000000 --- a/docs/tutorials/015/Handler.cpp +++ /dev/null @@ -1,179 +0,0 @@ - -// $Id$ - -#include "Handler.h" -#include "Protocol_Task.h" - -/* The Protocol_Stream gives us the option to insert a Protocol_Task - to process data received by the stream. We'll get into the details - more when we talk about the stream in detail. For now it's enough - to know that Handler_Task::recv() will be invoked by the stream - after data from the client has been received and processed (eg -- - decrypted, uncompressed, and whatever else the protocol requires.) -*/ -class Handler_Task : public Protocol_Task -{ -public: - - // Typical... - typedef Protocol_Task inherited; - - // Simple... - Handler_Task(void); - ~Handler_Task(void); - -protected: - - // recv() is invoked after received data has been fully - // processed by the protocol rules. Data processing typically - // done in handle_input() can then be done here. - int recv(ACE_Message_Block * message, - ACE_Time_Value *timeout = 0); -}; - -Handler::Handler(void) -{ - ; -} - -Handler::~Handler(void) -{ - ; -} - -/* The Acceptor will open() us once the peer() connection is - established. There are a couple of things we have to do here - before we're ready to receive data from the client. -*/ -int Handler::open (void *) -{ - ACE_INET_Addr addr; - - // Make sure that we can get the peer's address. If we can't - // then there may be a network error or something else that - // will prevent communicating with the client. This is - // something you'll want to do in every event handler you create. - if (this->peer ().get_remote_addr (addr) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't get remote addr\n"), -1); - - // Announce the client - ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name() )); - - // Here's the first new twist to the old event handler. - // Before we can use the Protocol_Stream to communicate with - // the peer, we must open() it. We provide the stream with - // the peer() so that it will have a valid socket on which to - // read client requests and send our responses. We also - // provide a Handler_Task instance that will ultimately be - // responsible for processing any client data we receive. - int rval = stream().open( this->peer(), new Handler_Task() ); - - // Of course, we have to account for the chance that the - // stream's open() may fail. - if( rval == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't open the protocol stream.\n"), -1); - } - - // Now that we know the client is valid and that the stream is - // ready for business we can register with the gloabl reactor - // instance. Here again is an opportunity for improvement if - // we expect to have mulitple Server object instances. - if (ACE_Reactor::instance()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1); - - return rval; -} - -/* This is a fairly typical destroy() method that can be shared by - both close() and handle_close(). -*/ -void Handler::destroy (void) -{ - ACE_Reactor::instance()->remove_handler(this,ACE_Event_Handler::READ_MASK|ACE_Event_Handler::DONT_CALL); - - this->peer ().close (); - - delete this; -} - -/* In this simple application we just forward the close() and - handle_close() requests right on to the destroy() method. -*/ - -int Handler::close (u_long) -{ - this->destroy (); - return 0; -} - -int Handler::handle_close(ACE_HANDLE, ACE_Reactor_Mask _mask) -{ - this->destroy(); - return 0; -} - -/* Unlike a "traditional" handle_input() ours is very simple. Because - of the use of the protocol stream, we delegate the read function to - the stream's get() and rely on our Handler_Task to do the real work. -*/ -int Handler::handle_input (ACE_HANDLE) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Activity from client\n" )); - - // This will cause a blocking read from the peer(). The data - // will then be pushed through the protocol stream. - if( stream().get( ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't get data from protocol stream\n"), -1); - } - - return 0; -} - -/* A Protocol_Task is derived from ACE_Task and has the option of - running in one or more threads. I've chosen here to construct the - baseclass with no threads but it should work just fine with one or - more if you need. Unless you're sharing the Handler_Task with - several peers, however, you're probably just wasting a thread to - activate it. On the other hand, if your reactor is running in a - single thread (as in this example) then you can easily implement - thread-per-connectin concurrency by giving the baseclass one thread. -*/ -Handler_Task::Handler_Task(void) - : inherited(0) -{ - ; -} - -Handler_Task::~Handler_Task(void) -{ - ; -} - -/* When installed into the protocol stream, the Handler_Task's recv() - method will be called when data is ready for processing. - */ -int Handler_Task::recv(ACE_Message_Block * message, - ACE_Time_Value *timeout ) -{ - // Announce the request we got from the client - ACE_DEBUG ((LM_INFO, "(%P|%t) Handler_Task::recv() got (%s)\n", message->rd_ptr() )); - - // Create a response message to send to the client - ACE_Message_Block * response = new ACE_Message_Block( 128 ); - - // Nothing very original about this I'm afraid... - ACE_OS::sprintf( response->wr_ptr(), "You Said: (%s)", message->rd_ptr() ); - response->wr_ptr( strlen(response->wr_ptr())+1 ); - - // Release the original message block now that we're through - // "processing" it. - message->release(); - - // Turn the message around and send it back down the Stream. - // In other words, we invoke the put() method on the - // Protocol_Stream without having to have a direct reference - // to the stream object. - return this->reply( response, timeout ); -} diff --git a/docs/tutorials/015/Handler.h b/docs/tutorials/015/Handler.h deleted file mode 100644 index 73aa2573b0c..00000000000 --- a/docs/tutorials/015/Handler.h +++ /dev/null @@ -1,66 +0,0 @@ - -// $Id$ - -#ifndef HANDLER_H -#define HANDLER_H - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" -#include "Protocol_Stream.h" - -/* Just your basic event handler. We use ACE_Svc_Handler<> as a - baseclass so that it can maintain the peer() and other details for - us. We're not going to activate() this object, so we can get away - with the NULL synch choice. -*/ -class Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - - Handler(void); - ~Handler(void); - - // Called by the acceptor when we're created in response to a - // client connection. - int open (void *); - - // Called when it's time for us to be deleted. We take care - // of removing ourselves from the reactor and shutting down - // the peer() connectin. - void destroy (void); - - // Called when it's time for us to go away. There are subtle - // differences between destroy() and close() so don't try to - // use either for all cases. - int close (u_long); - -protected: - - // Respond to peer() activity. - int handle_input (ACE_HANDLE); - - // This will be called when handle_input() returns a failure - // code. That's our signal that it's time to begin the - // shutdown process. - int handle_close(ACE_HANDLE, ACE_Reactor_Mask _mask); - -private: - - // Like the Client, we have to abide by the protocol - // requirements. We use a local Protocol_Stream object to - // take care of those details. For us, I/O then just becomes - // a matter of interacting with the stream. - Protocol_Stream stream_; - - Protocol_Stream & stream(void) - { - return this->stream_; - } -}; - -#endif // HANDLER_H diff --git a/docs/tutorials/015/Makefile b/docs/tutorials/015/Makefile deleted file mode 100644 index 60733fb4e87..00000000000 --- a/docs/tutorials/015/Makefile +++ /dev/null @@ -1,30 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client server - -all clean realclean : # - $(MAKE) -f Makefile.client $@ - $(MAKE) -f Makefile.server $@ - -client server : # - $(MAKE) -f Makefile.$@ all - -Depend : # - $(MAKE) -f Makefile.client $@ - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - chmod +r *.html - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre *.pst > combine.shar && rm -f hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar diff --git a/docs/tutorials/015/Makefile.client b/docs/tutorials/015/Makefile.client deleted file mode 100644 index 20680aea15b..00000000000 --- a/docs/tutorials/015/Makefile.client +++ /dev/null @@ -1,79 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client - -FILES += Protocol_Stream -FILES += Protocol_Task -FILES += Xmit -FILES += Recv -FILES += Compressor -FILES += Crypt -FILES += Client_i - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -HDR = *.h - -MAKEFILE = Makefile.client -DEPEND = .depend.client - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -HTML : # - perl ../combine *.html - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile -f $(MAKEFILE) -o $(DEPEND) - -$(DEPEND) : - touch $(DEPEND) - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include $(DEPEND) -include .depend.client diff --git a/docs/tutorials/015/Makefile.server b/docs/tutorials/015/Makefile.server deleted file mode 100644 index 109cecc8e90..00000000000 --- a/docs/tutorials/015/Makefile.server +++ /dev/null @@ -1,81 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server - -FILES += Protocol_Stream -FILES += Protocol_Task -FILES += Xmit -FILES += Recv -FILES += Compressor -FILES += Crypt - -FILES += Handler -FILES += Server_i - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -HDR = *.h - -MAKEFILE = Makefile.server -DEPEND = .depend.server - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -HTML : # - perl ../combine *.html - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile -f $(MAKEFILE) -o $(DEPEND) - -$(DEPEND) : - touch $(DEPEND) - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include $(DEPEND) -include .depend.server diff --git a/docs/tutorials/015/Protocol_Stream.cpp b/docs/tutorials/015/Protocol_Stream.cpp deleted file mode 100644 index 058ec300b2d..00000000000 --- a/docs/tutorials/015/Protocol_Stream.cpp +++ /dev/null @@ -1,171 +0,0 @@ - -// $Id$ - -#include "Protocol_Stream.h" -#include "Protocol_Task.h" - -#include "Xmit.h" -#include "Recv.h" - -#include "Compressor.h" -#include "Crypt.h" - -#include "ace/Stream_Modules.h" - -/* You can choose at compile time to include/exclude the protocol - pieces. -*/ -#define ENABLE_COMPRESSION -#define ENABLE_ENCRYPTION - -// The usual typedefs to make things easier to type. -typedef ACE_Module<ACE_MT_SYNCH> Module; -typedef ACE_Thru_Task<ACE_MT_SYNCH> Thru_Task; - -/* Do-nothing constructor and destructor - */ - -Protocol_Stream::Protocol_Stream( void ) -{ - ; -} - -Protocol_Stream::~Protocol_Stream( void ) -{ - ; -} - -/* Even opening the stream is rather simple. The important thing to - rememer is that the modules you push onto the stream first will be - at the tail (eg -- most downstream) end of things when you're - done. - */ -int Protocol_Stream::open( ACE_SOCK_Stream & _peer, Protocol_Task * _reader ) -{ - // Initialize our peer() to read/write the socket we're given - peer_.set_handle( _peer.get_handle() ); - - // Construct (and remember) the Recv object so that we can - // read from the peer(). - recv_ = new Recv( peer() ); - - // Add the transmit and receive tasks to the head of the - // stream. As we add more modules these will get pushed - // downstream and end up nearest the tail by the time we're - // done. - if( stream().push( new Module( "Xmit/Recv", new Xmit( peer() ), recv_ ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "stream().push( xmit/recv )"), -1); - } - - // Add any other protocol tasks to the stream. Each one is - // added at the head. The net result is that Xmit/Recv are at - // the tail. - if( this->open() == -1 ) - { - return(-1); - } - - // If a reader task was provided then push that in as the - // upstream side of the next-to-head module. Any data read - // from the peer() will be sent through here last. Server - // applications will typically use this task to do the actual - // processing of data. - // Note the use of Thru_Task. Since a module must always have - // a pair of tasks we use this on the writter side as a no-op. - if( _reader ) - { - if( stream().push( new Module( "Reader", new Thru_Task(), _reader ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "stream().push( reader )"), -1); - } - } - - return(0); -} - -/* Add the necessary protocol objects to the stream. The way we're - pushing things on we will encrypt the data before compressing it. -*/ -int Protocol_Stream::open(void) -{ -#if defined(ENABLE_COMPRESSION) - if( stream().push( new Module( "compress", new Compressor(), new Compressor() ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "stream().push( comprssor )"), -1); - } -#endif // ENABLE_COMPRESSION - -#if defined(ENABLE_ENCRYPTION) - if( stream().push( new Module( "crypt", new Crypt(), new Crypt() ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "stream().push( crypt )"), -1); - } -#endif // ENABLE_ENCRYPTION - return( 0 ); -} - -// Closing the Protocol_Stream is as simple as closing the ACE_Stream. -int Protocol_Stream::close(void) -{ - return stream().close(); -} - -// Simply pass the data directly to the ACE_Stream. -int Protocol_Stream::put(ACE_Message_Block * & _message, ACE_Time_Value * _timeout ) -{ - return stream().put(_message,_timeout); -} - -/* Tell the Recv module to read some data from the peer and pass it - upstream. Servers will typically use this method in a - handle_input() method to tell the stream to get a client's request. -*/ -int Protocol_Stream::get(void) -{ - // If there is no Recv module, we're in big trouble! - if( ! recv_ ) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) No Recv object!\n"), -1); - } - - // This tells the Recv module to go to it's peer() and read - // some data. Once read, that data will be pushed upstream. - // If there is a reader object then it will have a chance to - // process the data. If not, the received data will be - // available in the message queue of the stream head's reader - // object (eg -- stream().head()->reader()->msg_queue()) and - // can be read with our other get() method below. - if( recv_->get() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) Cannot queue read request\n"), -1); - } - - // For flexibility I've added an error() method to tell us if - // something bad has happened to the Recv object. - if( recv_->error() ) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) Recv object error!\n"), -1); - } - - return(0); -} - -/* Take a message block off of the stream head reader's message - queue. If the queue is empty, use get() to read from the peer. - This is most often used by client applications. Servers will - generaly insert a reader that will prevent the data from getting - all the way upstream to the head. -*/ -int Protocol_Stream::get(ACE_Message_Block * & _response, ACE_Time_Value * _timeout ) -{ - if( stream().head()->reader()->msg_queue()->is_empty() ) - { - if( this->get() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) Cannot get data into the stream.\n"), -1); - } - } - - return stream().head()->reader()->getq(_response,_timeout); -} diff --git a/docs/tutorials/015/Protocol_Stream.h b/docs/tutorials/015/Protocol_Stream.h deleted file mode 100644 index 686d39126e0..00000000000 --- a/docs/tutorials/015/Protocol_Stream.h +++ /dev/null @@ -1,86 +0,0 @@ - -// $Id$ - -#ifndef PROTOCOL_STREAM_H -#define PROTOCOL_STREAM_H - -#include "ace/SOCK_Stream.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/Stream.h" - -// Shorthand for the stream. -typedef ACE_Stream<ACE_MT_SYNCH> Stream; - -// Forward references to cut down on the number of #includes -class ACE_Message_Block; -class Recv; -class Protocol_Task; - -/* The Protocol_Stream provides a tidy interface to an ACE_Stream - setup to process a data block through a series of protocol stages. -*/ -class Protocol_Stream -{ -public: - Protocol_Stream(void); - ~Protocol_Stream(void); - - // Provide the stream with an ACE_SOCK_Stream on which it can - // communicate. If _reader is non-null, it will be added as - // the reader task just below the stream head so that it can - // process data read from the peer. - int open( ACE_SOCK_Stream & _peer, Protocol_Task * _reader = 0 ); - - // Close the stream. All of the tasks & modules will also be closed. - int close(void); - - // putting data onto the stream will pass it through all - // protocol levels and send it to the peer. - int put( ACE_Message_Block * & _message, ACE_Time_Value * - _timeout = 0 ); - - // get will cause the Recv task (at the tail of the stream) to - // read some data from the peer and pass it upstream. The - // message block is then taken from the stream reader task's - // message queue. - int get( ACE_Message_Block * & _response, ACE_Time_Value * - _timeout = 0 ); - - // Tell the Recv task to read some data and send it upstream. - // The data will pass through the protocol tasks and be queued - // into the stream head reader task's message queue. If - // you've installed a _reader in open() then that task's - // recv() method will see the message and may consume it - // instead of passing it to the stream head for queueing. - int get(void); - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } - -private: - // Our peer connection - ACE_SOCK_Stream peer_; - - // The stream managing the various protocol tasks - Stream stream_; - - // A task which is capable of receiving data on a socket. - // Note that this is only useful by client-side applications. - Recv * recv_; - - Stream & stream(void) - { - return this->stream_; - } - - // Install the protocol tasks into the stream. - int open(void); -}; - -#endif // PROTOCOL_STREAM_H diff --git a/docs/tutorials/015/Protocol_Task.cpp b/docs/tutorials/015/Protocol_Task.cpp deleted file mode 100644 index 3cfe7495539..00000000000 --- a/docs/tutorials/015/Protocol_Task.cpp +++ /dev/null @@ -1,146 +0,0 @@ - -// $Id$ - -#include "Protocol_Task.h" - -// Construct the object and remember the thread count. -Protocol_Task::Protocol_Task( int _thr_count ) - : desired_thr_count_(_thr_count) -{ -} - -Protocol_Task::~Protocol_Task(void) -{ -} - -// Activate the object if necessary. -int Protocol_Task::open(void *arg) -{ - ACE_UNUSED_ARG(arg); - - if( desired_thr_count_ ) - { - return this->activate(THR_NEW_LWP, desired_thr_count_); - } - - return(0); -} - -/* When we're being closed by the ACE_Stream and we've got threads to - worry about then we drop a hangup message onto the message queue so - that svc() will go away. Except for the call to is_active(), this - is lifted directly from Tutorial 14. -*/ -int Protocol_Task::close(u_long flags) -{ - if (flags == 1 && is_active() ) - { - ACE_Message_Block *hangupBlock = new ACE_Message_Block(); - - hangupBlock->msg_type(ACE_Message_Block::MB_HANGUP); - - if (this->putq(hangupBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::close() putq"), -1); - } - - hangupBlock->release(); - - return this->wait(); - } - - return 0; -} - -/* The put() method has to make a decision. If we've got threads then - put the unit of work onto the message queue for svc() to deal - with. If not then process() it directly. -*/ -int Protocol_Task::put(ACE_Message_Block *message,ACE_Time_Value *timeout) -{ - if( is_active() ) - { - return this->putq(message,timeout); - } - - return this->process(message,timeout); -} - -/* svc() is about what you would expect. This is again lifted - directly from Tutorial 14 but with a call to process() for handling - the logic instead of doing the work right here. - */ -int Protocol_Task::svc(void) -{ - ACE_Message_Block * message; - - while (1) - { - // Get a message - if ( this->getq(message, 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Protocol_Task::svc() getq"), -1); - } - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Protocol_Task::svc() got message\n")); - - // Check for hangup - if (message->msg_type() == ACE_Message_Block::MB_HANGUP) { - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) Protocol_Task::svc() -- HANGUP block received\n")); - - // Hangup our thread-pool peers (if any) - if (this->putq(message->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Protocol_Task::svc() putq"), -1); - } - - // Leave svc() - break; - } - - // Do some work on the data. - if( this->process(message->duplicate(),0) == -1 ) - { - break; - } - - // Give up the message block before we go get another. - message->release(); - } - - // Give up the message block that caused us to exit the - // while(1) loop. - message->release(); - - return(0); -} - -/* There's nothing really magic about process(). We just decide if - we're moving data upstream or downstream and invoke the appropriate - virtual function to handle it. -*/ -int Protocol_Task::process(ACE_Message_Block * message, ACE_Time_Value *timeout) -{ - if( this->is_writer() ) - { - return this->send(message,timeout); - } - - return this->recv(message,timeout); -} - -/* We must insist that derivatives provide a meaningful overload for - these methods. It's fairly common for ACE object methods to return - an error when an overload is expected but the method cannot be - safely made pure virtual. - */ - -int Protocol_Task::send(ACE_Message_Block *message, - ACE_Time_Value *timeout) -{ - return -1; -} - -int Protocol_Task::recv(ACE_Message_Block * message, - ACE_Time_Value *timeout) -{ - return -1; -} diff --git a/docs/tutorials/015/Protocol_Task.h b/docs/tutorials/015/Protocol_Task.h deleted file mode 100644 index 194809327ec..00000000000 --- a/docs/tutorials/015/Protocol_Task.h +++ /dev/null @@ -1,74 +0,0 @@ - -// $Id$ - -#ifndef PROTOCOL_TASK_H -#define PROTOCOL_TASK_H - -#include "ace/Task.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* A typical ACE_Task<> derivative that adds a few things appropriate - to protocol stacks. -*/ -class Protocol_Task : public ACE_Task<ACE_MT_SYNCH> -{ -public: - - typedef ACE_Task<ACE_MT_SYNCH> inherited; - - // A choice of concurrency strategies is offered by the - // constructor. In most cases it makes sense to set this to - // zero and let things proceed serially. You might have a - // need, however, for some of your tasks to have their own thread. - Protocol_Task( int _thr_count ); - - ~Protocol_Task(void); - - // open() is invoked when the task is inserted into the stream. - virtual int open(void *arg); - - // close() is invoked when the stream is closed (flags will be - // set to '1') and when the svc() method exits (flags will be - // '0'). - virtual int close(u_long flags); - - // As data travels through the stream, the put() method of - // each task is invoked to keep the data moving along. - virtual int put(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - // If you choose to activate the task then this method will be - // doing all of the work. - virtual int svc(void); - -protected: - - // Called by put() or svc() as necessary to process a block of - // data. - int process(ACE_Message_Block * message, ACE_Time_Value *timeout); - - // Just let us know if we're active or not. - int is_active(void) - { - return this->thr_count() != 0; - } - - // Tasks on the writter (downstream) side of the stream - // are called upon to send() data that will ultimately go to - // the peer. - virtual int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - // Tasks on the reader (upstream) side will be receiving data - // that came from the peer. - virtual int recv(ACE_Message_Block * message, - ACE_Time_Value *timeout); - -private: - int desired_thr_count_; -}; - -#endif // PROTOCOL_TASK_H diff --git a/docs/tutorials/015/Recv.cpp b/docs/tutorials/015/Recv.cpp deleted file mode 100644 index 626d6298290..00000000000 --- a/docs/tutorials/015/Recv.cpp +++ /dev/null @@ -1,85 +0,0 @@ - -// $Id$ - -#include "Recv.h" -#include "ace/SOCK_Stream.h" - -/* Construct the object with the peer reference and other appropriate - initializations. -*/ -Recv::Recv( ACE_SOCK_Stream & _peer ) - : Protocol_Task(0), peer_(_peer), error_(0) -{ - // Create the tickler that get() will use to trigger recv() - // through the baseclass. Since we're single-threaded this is - // probably overkill but it makes multi-threading easier if we - // choose to do that. - tickler_ = new ACE_Message_Block(1); -} - -/* Be sure we manage the lifetime of the tickler to prevent a memory - leak. -*/ -Recv::~Recv(void) -{ - tickler_->release(); -} - -/* By putting the tickler to ourselves we cause things to happen in - the baseclass that will invoke recv(). If we know we're single - threaded we could directly call recv() and be done with it but then - we'd have to do something else if we're multi-threaded. Just let - the baseclass worry about those things! -*/ -int Recv::get(void) -{ - return this->put( tickler_, 0 ); -} - -int Recv::recv(ACE_Message_Block * message, ACE_Time_Value *timeout) -{ - int rval; - - /* Xmit will send us the message length in clear-text. I - assume that will be less than 32-bytes! - */ - char msize[32]; - int b = 0; - - /* Read from the socket one byte at a time until we see then - end-of-string NULL character. Since the OS layers (at leas - in Unix) will provide some buffering this isn't as bad as - it may seem at first. - */ - do - { - rval = this->peer().recv( &msize[b], 1, timeout ); - if( rval == -1 ) - { - error_ = 1; - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Recv::recv() Failed to get message size."), -1); - } - } - while( msize[b++] != 0 ); - - int size = ACE_OS::atoi(msize); - - // Make a block big enough to contain the data we'll read - message = new ACE_Message_Block( size ); - - // Read the actual message data into our new message block - rval = this->peer().recv_n( message->wr_ptr(), size, 0, timeout ); - - // If we got the data correctly then send it on upstream. - if( rval > 0 ) - { - message->wr_ptr( rval ); - return( this->put_next( message ) ); - } - - // Something bad happend on the recv_n(). Set an error flag - // and return error. - error_ = 1; - - return( -1 ); -} diff --git a/docs/tutorials/015/Recv.h b/docs/tutorials/015/Recv.h deleted file mode 100644 index a7058435bf5..00000000000 --- a/docs/tutorials/015/Recv.h +++ /dev/null @@ -1,62 +0,0 @@ - -// $Id$ - -#ifndef RECV_H -#define RECV_h - -#include "Protocol_Task.h" - -class ACE_SOCK_Stream; - -/* Get some data from the peer and send it upstream for - de-protocol-ization. -*/ -class Recv : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - // Give it someone to talk to... - Recv( ACE_SOCK_Stream & _peer ); - - ~Recv(void); - - // Trigger a read from the socket - int get(void); - - // In some cases it might be easier to check the "state" of the - // Recv object than to rely on return codes filtering back to - // you. - int error(void) - { - return this->error_; - } - -protected: - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } - - // The baseclass will trigger this when our get() method is - // called. A message block of the appropriate size is created, - // filled and passed up the stream. - int recv(ACE_Message_Block * message, - ACE_Time_Value *timeout = 0); - -private: - // Our endpoint - ACE_SOCK_Stream & peer_; - - // get() uses a bogus message block to cause the baseclass to - // invoke recv(). To avoid memory thrashing, we create that - // bogus message once and reuse it for the life of Recv. - ACE_Message_Block * tickler_; - - // Our error flag (duh) - int error_; -}; - -#endif // RECV_H diff --git a/docs/tutorials/015/Server_i.cpp b/docs/tutorials/015/Server_i.cpp deleted file mode 100644 index dedbcd720f6..00000000000 --- a/docs/tutorials/015/Server_i.cpp +++ /dev/null @@ -1,71 +0,0 @@ - -// $Id$ - -#include "Server_i.h" - -/* We have to allocate space for our static finished_ flag. We also - initialize it to 'false' so that we don't exit immediately. -*/ -sig_atomic_t Server::finished_ = 0; - -/* The simple constructor and destructor don't do anything but give us - a place to expand in the future if we want. -*/ -Server::Server(void) -{ - ; -} - -Server::~Server(void) -{ - ; -} - -/* Opening the server is as simple as opening the acceptor with the - default ACE_Reactor instance. If we want to allow multiple - instances of Server objects then we should have an ACE_Reactor - member variable that we can register with. -*/ -int Server::open(void) -{ - if (acceptor_.open (ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT), ACE_Reactor::instance()) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); - - return(0); -} - -/* Running the server just means that we execute the basic event - loop for the reactor. Again, if we had a private reactor then we - could have multiple server's in their run() method. -*/ -int Server::run(void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n")); - - ACE_Time_Value timeout(2); - - // Here's the basic event loop. I have a 2-second timeout on - // the handle_events() so that we don't have to wait too long - // when we set the finished_ flag. - while (!finished_) - { - ACE_Reactor::instance()->handle_events (&timeout); - } - - // Close the acceptor when we're done. This may be handled by - // the framework but it's good practice to be explicit about things. - acceptor_.close(); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server daemon\n")); - - return 0; -} - -/* The close() method simply sets the finished_ flag so that run() - will leave the event loop and exit. -*/ -int Server::close(void) -{ - finished_ = 1; - return(0); -} diff --git a/docs/tutorials/015/Server_i.h b/docs/tutorials/015/Server_i.h deleted file mode 100644 index 6b1eecf05e5..00000000000 --- a/docs/tutorials/015/Server_i.h +++ /dev/null @@ -1,52 +0,0 @@ - -// $Id$ - -#ifndef SERVER_H -#define SERVER_H - -#include "ace/Acceptor.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Acceptor.h" -#include "Handler.h" - -/* Anytime I have templates I try to remember to create a typedef for - the parameterized object. It makes for much less typing later! -*/ -typedef ACE_Acceptor < Handler, ACE_SOCK_ACCEPTOR > Acceptor; - -class Server -{ -public: - // Our simple constructor takes no parameters. To make the - // server a bit more useful, you may want to pass in the - // TCP/IP port to be used by the acceptor. - Server(void); - ~Server(void); - - // Open the server for business - int open(void); - - // Close all server instances by setting the finished_ flag. - // Actually, the way this class is written, you can only have - // one instance. - static int close(void); - - // Run the server's main loop. The use of the gloabl - // ACE_Reactor by this method is what limits us to one Server - // instance. - int run(void); - -private: - // This will accept client connection requests and instantiate - // a Handler object for each new connection. - Acceptor acceptor_; - - // Our shutdown flag - static sig_atomic_t finished_; -}; - -#endif // SERVER_H diff --git a/docs/tutorials/015/Xmit.cpp b/docs/tutorials/015/Xmit.cpp deleted file mode 100644 index 28cc7055ce6..00000000000 --- a/docs/tutorials/015/Xmit.cpp +++ /dev/null @@ -1,84 +0,0 @@ - -// $Id$ - -#include "Xmit.h" -#include "ace/SOCK_Stream.h" - -/* Construct the object with the peer connection and choose not to - activate ourselves into a dedicated thread. You might get some - performance gain by activating but if you really want a - multi-threaded apprroach you should handle that as a separate - issue. Attempting to force threading at this level will likely - cause more trouble than you want to deal with. -*/ -Xmit::Xmit( ACE_SOCK_Stream & _peer ) - : Protocol_Task(0), peer_(_peer) -{ -} - -Xmit::~Xmit(void) -{ -} - -/* Check to see if we're being closed by the stream (flags != 0) or if - we're responding to the exit of our svc() method. -*/ -int Xmit::close(u_long flags) -{ - // Take care of the baseclass closure. - int rval = inherited::close(flags); - - // Only if we're being called at the stream shutdown do we close - // the peer connection. If, for some reason, we were activated - // into one or more threads we wouldn't want to close the pipe - // before all threads had a chance to flush their data. - if( flags ) - { - peer().close(); - } - - return( rval ); -} - -/* Our overload of send() will take care of sending the data to the - peer. -*/ -int Xmit::send(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - int rval; - - ACE_DEBUG ((LM_INFO, "(%P|%t) Xmit::send() sending (%s)(%d)\n", message->rd_ptr(), message->length() )); - - /* Since we're going to be sending data that may have been - compressed and encrypted it's probably important for the - receiver to get an entire "block" instead of having a - partial read. - - For that reason, we'll send the length of the message block - (in clear-text) to the peer so that it can then recv_n() - the entire block contents in one read operation. - */ - char msize[32]; - sprintf(msize,"%d",message->length()); - - // Be sure we send the end-of-string NULL so that Recv will - // know when to stop assembling the length. - rval = this->peer().send_n( msize, strlen(msize)+1, 0, timeout ); - - if( rval == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Xmit::send() Failed to send message size."), -1); - } - - /* Now we send the actual data. If you're worried about - network efficiency then you may choose to create one buffer - containing msize and the message data and send it all at - once. - */ - rval = this->peer().send_n( message->rd_ptr(), message->length(), 0, timeout ); - - // Release the message block since we're done with it. - message->release(); - - return( rval ); -} diff --git a/docs/tutorials/015/Xmit.h b/docs/tutorials/015/Xmit.h deleted file mode 100644 index 097f3afdaba..00000000000 --- a/docs/tutorials/015/Xmit.h +++ /dev/null @@ -1,49 +0,0 @@ - -// $Id$ - -#ifndef XMIT_H -#define XMIT_h - -#include "Protocol_Task.h" - -// Forward reference reduces #include dependencies -class ACE_SOCK_Stream; - -/* A class suitable for sending data to a peer from within an - ACE_Stream. - */ -class Xmit : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - // We must be given a valid peer when constructed. Without that - // we don't know who to send data to. - Xmit( ACE_SOCK_Stream & _peer ); - - ~Xmit(void); - - // As you know, close() will be called in a couple of ways by the - // ACE framework. We use that opportunity to terminate the - // connection to the peer. - int close(u_long flags); - -protected: - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } - - // Send the data to the peer. By now it will have been - // completely protocol-ized by other tasks in the stream. - int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - -private: - // A representation of the peer we're talking to. - ACE_SOCK_Stream & peer_; -}; - -#endif // XMIT_H diff --git a/docs/tutorials/015/client.cpp b/docs/tutorials/015/client.cpp deleted file mode 100644 index a573b4f3902..00000000000 --- a/docs/tutorials/015/client.cpp +++ /dev/null @@ -1,70 +0,0 @@ - -// $Id$ - -/* The Client object will implement the nasty details of connecting to - communicating with the server -*/ -#include "Client_i.h" - -int main(int argc, char *argv[]) -{ - // How many messages will we send? - int mcount = argc > 1 ? ACE_OS::atoi(argv[1]) : 3; - - // Construct a Client with our desired endpoint. - Client client(ACE_DEFAULT_SERVER_PORT,ACE_DEFAULT_SERVER_HOST); - - // Attempt to open the connection to the server. - if( client.open() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Client::open()"), -1); - } - - // Send a few messages to the server and get some responses... - for( int i = 0 ; i < mcount ; ++i ) - { - // Since we'll be using a Protocol Stream (even though we - // don't know that at this level) we require the use of - // ACE_Message_Block objects to send/receive data. - ACE_Message_Block * message = new ACE_Message_Block( 128 ); - - // Construct a silly message to send to the server. - // Notice that we're careful to add one to the strlen() so - // that we also send the end-of-string NULL character. - ACE_OS::sprintf (message->wr_ptr (), "This is message %d.", i); - message->wr_ptr (strlen (message->rd_ptr ())+1); - - // client will take ownership of the message block so that - // we don't have to remember to release(). We *do* have - // to remember not to use it after put() since it may be - // released almost immediately. - client.put( message ); - - ACE_Message_Block * response; - - // get() takes an ACE_Message_Block pointer reference. We then - // assume ownership of it and must release() when we're done. - if( client.get( response ) == -1 ) - { - ACE_DEBUG ((LM_INFO, "(%P|%t) Failed to get response from server\n" )); - break; - } - - ACE_DEBUG ((LM_INFO, "(%P|%t) The server's response: (%s)\n", - response->rd_ptr())); - - // Now that we're through with the response we have to - // release() it to avoid memory leaks. - response->release(); - } - - ACE_DEBUG ((LM_INFO, "(%P|%t) Shutting down the stream\n" )); - - // Before we exit, it's a good idea to properly close() the connection. - if( client.close() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Client::close()"), -1); - } - - return(0); -} diff --git a/docs/tutorials/015/combine.shar b/docs/tutorials/015/combine.shar deleted file mode 100644 index 800c35231fd..00000000000 --- a/docs/tutorials/015/combine.shar +++ /dev/null @@ -1,1004 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-10-22 19:58 EDT by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/015'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 414 -rw-rw-r-- hdr -# 419 -rw-rw-r-- bodies -# 1183 -rw-rw-r-- page01.pre -# 194 -rw-rw-r-- page02.pre -# 318 -rw-rw-r-- page03.pre -# 178 -rw-rw-r-- page04.pre -# 304 -rw-rw-r-- page05.pre -# 418 -rw-rw-r-- page06.pre -# 321 -rw-rw-r-- page07.pre -# 501 -rw-rw-r-- page08.pre -# 640 -rw-rw-r-- page09.pre -# 978 -rw-rw-r-- page10.pre -# 334 -rw-rw-r-- page11.pre -# 334 -rw-rw-r-- page12.pre -# 326 -rw-rw-r-- page13.pre -# 540 -rw-rw-r-- page14.pre -# 770 -rw-rw-r-- page15.pre -# 660 -rw-rw-r-- page16.pre -# 213 -rw-rw-r-- page17.pre -# 372 -rw-rw-r-- page18.pre -# 281 -rw-rw-r-- page19.pre -# 356 -rw-rw-r-- page20.pre -# 151 -rw-rw-r-- page21.pre -# 2567 -rw-rw-r-- page22.pre -# 406 -rw-rw-r-- page04.pst -# 617 -rw-rw-r-- page09.pst -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh18487; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1019163798 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -41322d388f7bb6c8eba031c4a6ab53ce hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 414 -eq "$shar_count" || - $echo 'hdr:' 'original size' '414,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -# -# The client application specific files -# -PAGE=2 -client.cpp -Client_i.h -Client_i.cpp -# -# The server application specific files -# -server.cpp -Server_i.h -Server_i.cpp -Handler.h -Handler.cpp -# -# The basic protocol stream -# -Protocol_Stream.h -Protocol_Stream.cpp -Protocol_Task.h -Protocol_Task.cpp -# -# Send/Receive objects -# -XXmit.h -XXmit.cpp -Recv.h -Recv.cpp -# -# Protocol objects -# -Compressor.h -Compressor.cpp -Crypt.h -Crypt.cpp -SHAR_EOF - $shar_touch -am 1022195498 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -a6c99d6567b0640ad524b196dc43647e bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 419 -eq "$shar_count" || - $echo 'bodies:' 'original size' '419,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X -In a typical client/server system you will be sending and receiving -X data. That's the whole point after all. -<P> -In the client/server tutorials that we've done so far it was just a -X matter of sending a buffer of data to the peer. This was done -X with the send*() and recv*() methods of the ACE_SOCK* objects. -<P> -In a more robust system, one might want to process the data before -X sending it to a peer and "unprocess" it after reading from a -X peer. These processing steps might include encryption, -X compression, applying checksums or any number of other actions. -<P> -In this tutorial a Protocol_Stream object is created to encrypt and -X compress* data being sent between peers. Both client and server -X applications are presented as well. I present the application -level code first and then go into the details of the protocol stream -and it's helper objects. If the stream stuff in the application logic -is confusing then just read on by and come back to it after the later -discussions. -X -<P> -<font size=-1>* Ok, I didn't really implement encryption and -X compression objects. I'll leave that as a thought -X exercise!</font> -SHAR_EOF - $shar_touch -am 1019163798 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -2a7a0fad3e88fcaa6b70cedbf873192f page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 1183 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '1183,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -We'll take a look first at the client application. As usual, our goal -X is to keep the main() application as simple as possible and -X delegate the tricky stuff to another object. -X -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -6a2e64962c95b349625f418502c95952 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 194 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '194,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -The Client object is designed to hide all of the messy connection -X logic from it's users. It also provides put/get methods for -X sending data to the server and receiving the server's response. -X Note the Protocol_Stream member that will take care of -X converting and sending/receiving the data. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -95326c064b10bbda428d3c967f285760 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 318 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '318,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -The implementation of the Client object. Only the open() method -X really does any work. The other methods simply delegate their -X function to the Protocol_Stream. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -2955ca8d3b0fc6840f3d371aea528b8d page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 178 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '178,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -Like the client, we want to keep the main() part of our server code as -X simple as possible. This is done by putting most of the work -X into the Handler object that will deal with client connections. -XFrom the looks of the code below, I think we've been successful in our -simplification. -<HR> -X -SHAR_EOF - $shar_touch -am 1019163798 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -8833b0d7f90a4d13f68b8cdb9147c29a page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 304 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '304,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -The Server object exists in order simplify the -main() application level. To that end, it hides the details of -creating an acceptor and managing the reactor. -<P> -The static close() method available for a signal handler as you saw on -the previous page. Of course the assumption here is that there would -only be one Server instance but since you can't provide a TCP/IP port, -that's probably a valid assumption! -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pre:' 'MD5 check failed' -06a0abefdf4e704b42147f433bd27e4d page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 418 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '418,' 'current size' "$shar_count!" - fi -fi -# ============= page07.pre ============== -if test -f 'page07.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page07.pre' '(file already exists)' -else - $echo 'x -' extracting 'page07.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page07.pre' && -And now the implementation of Server. This is actually just the -main() code from a previous tutorial broken into appropriate method -calls. It may seem silly to do this rather than keeping the stuff in -main() but you'll find that you have less trouble enhancing an -application when you take this sort of approach. -<HR> -X -SHAR_EOF - $shar_touch -am 1019163798 'page07.pre' && - chmod 0664 'page07.pre' || - $echo 'restore of' 'page07.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page07.pre:' 'MD5 check failed' -7dfb75884939c3c05ee1e1000956e9f4 page07.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page07.pre'`" - test 321 -eq "$shar_count" || - $echo 'page07.pre:' 'original size' '321,' 'current size' "$shar_count!" - fi -fi -# ============= page08.pre ============== -if test -f 'page08.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page08.pre' '(file already exists)' -else - $echo 'x -' extracting 'page08.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page08.pre' && -The Handler object is our event handler. You can use either -ACE_Event_Handler or ACE_Svc_Handler<> for the baseclass. I generally -prefer the latter since it takes care of some housekeeping that I -would otherwise be responsible for. -<P> -The class declaration is taken almost exactly from a previous -tutorial. A good design will have a simple handler object that will -collect data from the peer and pass it along to another object for -processing. Again, keep it simple and delegate authority. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page08.pre' && - chmod 0664 'page08.pre' || - $echo 'restore of' 'page08.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page08.pre:' 'MD5 check failed' -471889eb736a025fc46719549bca160a page08.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page08.pre'`" - test 501 -eq "$shar_count" || - $echo 'page08.pre:' 'original size' '501,' 'current size' "$shar_count!" - fi -fi -# ============= page09.pre ============== -if test -f 'page09.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page09.pre' '(file already exists)' -else - $echo 'x -' extracting 'page09.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page09.pre' && -Like any other event handler, the handle_input() method will be -responsible for getting data from the peer() and doing something with -it. In this case, we have a Protocol_Stream to deal with. We'll use -the stream for the actual I/O but we are ultimately responsible for -processing the data from the peer. To do that, we've created a -Handler_Task that fits within the Protocol_Stream framework to process -data that has been received. Handler::handle_input() will tell the stream that -it's time to read data and that data will eventually show up at -Handler_Task::recv() where we'll process it as required by our -application logic. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page09.pre' && - chmod 0664 'page09.pre' || - $echo 'restore of' 'page09.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page09.pre:' 'MD5 check failed' -da5c4b11d356dc9caf3a8e3b6b2527a6 page09.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page09.pre'`" - test 640 -eq "$shar_count" || - $echo 'page09.pre:' 'original size' '640,' 'current size' "$shar_count!" - fi -fi -# ============= page10.pre ============== -if test -f 'page10.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page10.pre' '(file already exists)' -else - $echo 'x -' extracting 'page10.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page10.pre' && -And so finally we come to the Protocol_Stream. That, after all, is -the focus of the entire tutorial but it took us half of the day to get -here! -<P> -The Protocol_Stream uses an ACE_Stream to move an ACE_Message_Block -through a series of tasks. Each task in the stream is responsible for -performing some operation on the data in the message block. That is -the nature of a protocol stream (or "stack" if you prefer). In this -stream, the data is compressed and encrypted* on its way between -peers. We also allow users of the stream to install a reader task to -handle data that percolates up from the peer. As you saw a page or -two ago, this is most useful for a server. -X -<P> -<font size=-1>*Again, I just pretend to do these things. It would -take another day or two to go through any sort of reasonable -encryption or compression!</font> -<P> -Before we get into the code, here's a picture that's shows what's -going on here. -<P><center><img src="stream.gif"></center></p> -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page10.pre' && - chmod 0664 'page10.pre' || - $echo 'restore of' 'page10.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page10.pre:' 'MD5 check failed' -a74423390fb5217104c6d89d7f202e8b page10.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page10.pre'`" - test 978 -eq "$shar_count" || - $echo 'page10.pre:' 'original size' '978,' 'current size' "$shar_count!" - fi -fi -# ============= page11.pre ============== -if test -f 'page11.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page11.pre' '(file already exists)' -else - $echo 'x -' extracting 'page11.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page11.pre' && -And now the implementation of the Protocol_Stream. There are more -lines of code here than we've seen so far but it still isn't -complicated. The basic idea is to construct the ACE_Stream with our -set of protocol objects that will manipulate the data. Our primary -concern in this file is to get everything in the correct order! -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page11.pre' && - chmod 0664 'page11.pre' || - $echo 'restore of' 'page11.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page11.pre:' 'MD5 check failed' -b0e968102fb417b12710e99465f4e387 page11.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page11.pre'`" - test 334 -eq "$shar_count" || - $echo 'page11.pre:' 'original size' '334,' 'current size' "$shar_count!" - fi -fi -# ============= page12.pre ============== -if test -f 'page12.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page12.pre' '(file already exists)' -else - $echo 'x -' extracting 'page12.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page12.pre' && -And now the implementation of the Protocol_Stream. There are more -lines of code here than we've seen so far but it still isn't -complicated. The basic idea is to construct the ACE_Stream with our -set of protocol objects that will manipulate the data. Our primary -concern in this file is to get everything in the correct order! -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page12.pre' && - chmod 0664 'page12.pre' || - $echo 'restore of' 'page12.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page12.pre:' 'MD5 check failed' -b0e968102fb417b12710e99465f4e387 page12.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page12.pre'`" - test 334 -eq "$shar_count" || - $echo 'page12.pre:' 'original size' '334,' 'current size' "$shar_count!" - fi -fi -# ============= page13.pre ============== -if test -f 'page13.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page13.pre' '(file already exists)' -else - $echo 'x -' extracting 'page13.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page13.pre' && -The Protocol_Task implementation takes care of the open(), close(), -put() and svc() methods so that derivatives can concentrate on the -send() and recv() methods. After a while you find that most -ACE_Task<> derivatives look very similar in the four basic methods and -only need one or two additional to do any real work. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page13.pre' && - chmod 0664 'page13.pre' || - $echo 'restore of' 'page13.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page13.pre:' 'MD5 check failed' -8b74a6d79d158222928097a9bb1335db page13.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page13.pre'`" - test 326 -eq "$shar_count" || - $echo 'page13.pre:' 'original size' '326,' 'current size' "$shar_count!" - fi -fi -# ============= page14.pre ============== -if test -f 'page14.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page14.pre' '(file already exists)' -else - $echo 'x -' extracting 'page14.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page14.pre' && -The Xmit object knows how to send data to the peer. It sits at the -tail of the stream and gets everything that flows down from the head. -In keeping with the spirit of things, this object does only one thing -and doesn't concern itself with anyone else' details. -<P> -The only thing you might want to do is combine it with Recv. Why? -As you'll realize in a page or two, the Xmit and Recv objects must -interact if you're going to ensure a safe transit. By having a single -object it's easier to coordinate and maintain the interaction. -<HR> -SHAR_EOF - $shar_touch -am 1019203498 'page14.pre' && - chmod 0664 'page14.pre' || - $echo 'restore of' 'page14.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page14.pre:' 'MD5 check failed' -bfc300ca2da5b82a5e452713cbf2f544 page14.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page14.pre'`" - test 540 -eq "$shar_count" || - $echo 'page14.pre:' 'original size' '540,' 'current size' "$shar_count!" - fi -fi -# ============= page15.pre ============== -if test -f 'page15.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page15.pre' '(file already exists)' -else - $echo 'x -' extracting 'page15.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page15.pre' && -The implementation of Xmit isn't too complicated. If we choose to -combine it with the Recv task we simply lift the recv() method from -that object and drop it into this one. -<P> -Note that close() must decide if it's being called when the stream is -shutdown or when it's svc() method exits. Since we tell the baseclass -not to use any threads it's a safe bet that flags will always be -non-zero. Still, it's good practice to plan for the future by -checking the value. -<P> -Note also that when we send the data we prefix it with the data size. -This let's our sibling Recv ensure that an entire block is received -together. This can be very important for compression and encryption -processes which typically work better with blocks of data instead of -streams of data. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page15.pre' && - chmod 0664 'page15.pre' || - $echo 'restore of' 'page15.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page15.pre:' 'MD5 check failed' -0d79137eaedd73b820037fcafe6e16b6 page15.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page15.pre'`" - test 770 -eq "$shar_count" || - $echo 'page15.pre:' 'original size' '770,' 'current size' "$shar_count!" - fi -fi -# ============= page16.pre ============== -if test -f 'page16.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page16.pre' '(file already exists)' -else - $echo 'x -' extracting 'page16.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page16.pre' && -Recv is the sibling to Xmit. Again, they could be combined into a -single object if you want. -<P> -An ACE_Stream is designed to handle downstream traffic very -well. You put() data into it and it flows along towards the tail. -However, there doesn't seem to be a way to put data in such that it -will travel upstream. To get around that, I've added a get() method -to Recv that will trigger a read on the socket. Recv will then put -the data to the next upstream module and we're on our way. As noted -earlier, that data will eventually show up either in the <i>reader</i> -(if installed on the stream open()) or the stream head reader task's -message queue. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page16.pre' && - chmod 0664 'page16.pre' || - $echo 'restore of' 'page16.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page16.pre:' 'MD5 check failed' -2d89b3c894cfcfdfef47ae506913cdad page16.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page16.pre'`" - test 660 -eq "$shar_count" || - $echo 'page16.pre:' 'original size' '660,' 'current size' "$shar_count!" - fi -fi -# ============= page17.pre ============== -if test -f 'page17.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page17.pre' '(file already exists)' -else - $echo 'x -' extracting 'page17.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page17.pre' && -The Recv implementation is nearly as simple as Xmit. There's -opportunity for error when we get the message size and we have to -manage the lifetime of the tickler but other than that it's pretty -basic stuff. -<HR> -SHAR_EOF - $shar_touch -am 1019163798 'page17.pre' && - chmod 0664 'page17.pre' || - $echo 'restore of' 'page17.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page17.pre:' 'MD5 check failed' -7db337f2c6ec74d75560534dec550b0e page17.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page17.pre'`" - test 213 -eq "$shar_count" || - $echo 'page17.pre:' 'original size' '213,' 'current size' "$shar_count!" - fi -fi -# ============= page18.pre ============== -if test -f 'page18.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page18.pre' '(file already exists)' -else - $echo 'x -' extracting 'page18.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page18.pre' && -This and the next three pages present the protocol objects that -provide compression and encryption. If you were hoping to learn the -secrets of compression and encryption then I'm going to disappoint -you. There are some really good libraries out there that do this -stuff though and if anyone wants to integrate one of them into the -tutorial I'll be glad to take it! -<HR> -SHAR_EOF - $shar_touch -am 1019203698 'page18.pre' && - chmod 0664 'page18.pre' || - $echo 'restore of' 'page18.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page18.pre:' 'MD5 check failed' -dc5f706bd5a27009aed167c0b137648e page18.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page18.pre'`" - test 372 -eq "$shar_count" || - $echo 'page18.pre:' 'original size' '372,' 'current size' "$shar_count!" - fi -fi -# ============= page19.pre ============== -if test -f 'page19.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page19.pre' '(file already exists)' -else - $echo 'x -' extracting 'page19.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page19.pre' && -Here we implement the details of our compression. By having both -compression and decompression in one object it's easier to keep track -of implementation details. Splitting Xmit/Recv like I did will make -things more difficult if something has to change in their interaction. -<HR> -SHAR_EOF - $shar_touch -am 1019195798 'page19.pre' && - chmod 0664 'page19.pre' || - $echo 'restore of' 'page19.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page19.pre:' 'MD5 check failed' -4eb5dcd181f180d6c460971903efb288 page19.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page19.pre'`" - test 281 -eq "$shar_count" || - $echo 'page19.pre:' 'original size' '281,' 'current size' "$shar_count!" - fi -fi -# ============= page20.pre ============== -if test -f 'page20.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page20.pre' '(file already exists)' -else - $echo 'x -' extracting 'page20.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page20.pre' && -While I might be able to come up with a competitive compressor, I -don't have a snowball's chance to code up encryption. I'd be better -off piping the data through the standard Unix crypt command. -<P> -So, while I was lazy with Compress, I'm realistic with Crypt. I'll -show you the hooks and entry points and let someone else contribute an -encryptor. -<HR> -SHAR_EOF - $shar_touch -am 1019203798 'page20.pre' && - chmod 0664 'page20.pre' || - $echo 'restore of' 'page20.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page20.pre:' 'MD5 check failed' -7f75130d385a34b2c421a8d7cae69cc3 page20.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page20.pre'`" - test 356 -eq "$shar_count" || - $echo 'page20.pre:' 'original size' '356,' 'current size' "$shar_count!" - fi -fi -# ============= page21.pre ============== -if test -f 'page21.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page21.pre' '(file already exists)' -else - $echo 'x -' extracting 'page21.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page21.pre' && -The encryption implementation isn't any smarter than that of the -compressor. Still, the hooks are there for you to insert your -favorite library. -<HR> -SHAR_EOF - $shar_touch -am 1019203898 'page21.pre' && - chmod 0664 'page21.pre' || - $echo 'restore of' 'page21.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page21.pre:' 'MD5 check failed' -7f0f64452098cdef38c5496340a4b6c7 page21.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page21.pre'`" - test 151 -eq "$shar_count" || - $echo 'page21.pre:' 'original size' '151,' 'current size' "$shar_count!" - fi -fi -# ============= page22.pre ============== -if test -f 'page22.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page22.pre' '(file already exists)' -else - $echo 'x -' extracting 'page22.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page22.pre' && -Well, this has certainly been one of the more verbose tutorials to -date. I must say "thanks" to everyone who stuck it out this far! -<P> -A quick review of what we've done: -<UL> -X -<LI>Create a simple client application and Client object that uses a -Protocol Stream without really knowing how they work. The app (and -object) rely on the public interface of the Protocol Stream to get the -job done. At this level the protocol details are irrelevant. -<P> -<LI>Next, we create a simple server application and Server object -similar to the client. The Protocol Stream is of course used and we -have to know a little more so that we can insert a <i>reader</i> that -will ultimately process the data from the client. -<P> -<LI>We then go into the details of the Protocol_Stream implementation -and it's Protocol_Task object that forms the basis for the stream -tasks. Each object is kept as small and simple as possible to improve -reusability and future maintenance. -<P> -<LI>Finally, the individual protocol objects are discused. Separate -objects for the peer interface were created as well as the bogus -compressor and encryptor. The protocol can be extended or modified by -creating new such objects and installing them in the Protocol_Stream's -open() method. -X -</UL> -<P> -X -It doesn't sound like much but it certainly took a bunch of files to -get there. It's easy to get lost in the details when there's so much -to cover so you're encouraged to go over things a couple of times. -As always, enhancments of the tutorials is welcome! -<P> -Here's the complete file list: -<UL> -<LI><A HREF="client">Makefile</A> -<P> -<LI><A HREF="Makefile.client">client Makefile</A> -<LI><A HREF="client.cpp">client.cpp</A> -<LI><A HREF="Client_i.h">Client_i.h</A> -<LI><A HREF="Client_i.cpp">Client_i.cpp</A> -<P> -<LI><A HREF="Makefile.server">Server Makefile</A> -<LI><A HREF="server.cpp">server.cpp</A> -<LI><A HREF="Server_i.h">Server_i.h</A> -<LI><A HREF="Server_i.cpp">Server_i.cpp</A> -<LI><A HREF="Handler.h">Handler.h</A> -<LI><A HREF="Handler.cpp">Handler.cpp</A> -<P> -<LI><A HREF="Protocol_Stream.cpp">Protocol_Stream.cpp</A> -<LI><A HREF="Protocol_Stream.h">Protocol_Stream.h</A> -<LI><A HREF="Protocol_Task.cpp">Protocol_Task.cpp</A> -<LI><A HREF="Protocol_Task.h">Protocol_Task.h</A> -<P> -<LI><A HREF="Xmit.cpp">Xmit.cpp</A> -<LI><A HREF="Xmit.h">Xmit.h</A> -<LI><A HREF="Recv.cpp">Recv.cpp</A> -<LI><A HREF="Recv.h">Recv.h</A> -<P> -<LI><A HREF="Compressor.cpp">Compressor.cpp</A> -<LI><A HREF="Compressor.h">Compressor.h</A> -<LI><A HREF="Crypt.cpp">Crypt.cpp</A> -<LI><A HREF="Crypt.h">Crypt.h</A> -</UL> -SHAR_EOF - $shar_touch -am 1022195898 'page22.pre' && - chmod 0664 'page22.pre' || - $echo 'restore of' 'page22.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page22.pre:' 'MD5 check failed' -9eae1b08c2e061a68bfc1f3cbc2f59de page22.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page22.pre'`" - test 2567 -eq "$shar_count" || - $echo 'page22.pre:' 'original size' '2567,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pst ============== -if test -f 'page04.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pst' '(file already exists)' -else - $echo 'x -' extracting 'page04.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pst' && -<HR> -<P> -Ok, that's it for the client. We've seen a very simple main() -X followed by an equally simple Client object. -<P> -For a quick look back: -<UL> -<LI><A HREF="Makefile.client">client Makefile</A> -<LI><A HREF="client.cpp">client.cpp</A> -<LI><A HREF="Client_i.h">Client_i.h</A> -<LI><A HREF="Client_i.cpp">Client_i.cpp</A> -</UL> -<P> -Now we'll move on and examine the server counter-part of our client. -SHAR_EOF - $shar_touch -am 1022195698 'page04.pst' && - chmod 0664 'page04.pst' || - $echo 'restore of' 'page04.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pst:' 'MD5 check failed' -00419a8ab9a3ddae3261840b62afdc4a page04.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`" - test 406 -eq "$shar_count" || - $echo 'page04.pst:' 'original size' '406,' 'current size' "$shar_count!" - fi -fi -# ============= page09.pst ============== -if test -f 'page09.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page09.pst' '(file already exists)' -else - $echo 'x -' extracting 'page09.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page09.pst' && -<HR> -<P> -That's it for the server-specific code. I think I've been fairly -successful in keeping it simple and to the point. There are a couple -of places where the as-yet-undescribed Protocol_Stream pops up and may -cause confusion. We're going to discuss that mystery now but before -we do here's the list of server files if you want to review: -X -<UL> -<LI><A HREF="Makefile.server">Server Makefile</A> -<LI><A HREF="server.cpp">server.cpp</A> -<LI><A HREF="Server_i.h">Server_i.h</A> -<LI><A HREF="Server_i.cpp">Server_i.cpp</A> -<LI><A HREF="Handler.h">Handler.h</A> -<LI><A HREF="Handler.cpp">Handler.cpp</A> -</UL> -<P> -SHAR_EOF - $shar_touch -am 1022195698 'page09.pst' && - chmod 0664 'page09.pst' || - $echo 'restore of' 'page09.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page09.pst:' 'MD5 check failed' -a96009f43a6fe8e6b52ffa923993a3e1 page09.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page09.pst'`" - test 617 -eq "$shar_count" || - $echo 'page09.pst:' 'original size' '617,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh18487 -exit 0 diff --git a/docs/tutorials/015/page01.html b/docs/tutorials/015/page01.html deleted file mode 100644 index 7d8f425b972..00000000000 --- a/docs/tutorials/015/page01.html +++ /dev/null @@ -1,41 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - -In a typical client/server system you will be sending and receiving - data. That's the whole point after all. -<P> -In the client/server tutorials that we've done so far it was just a - matter of sending a buffer of data to the peer. This was done - with the send*() and recv*() methods of the ACE_SOCK* objects. -<P> -In a more robust system, one might want to process the data before - sending it to a peer and "unprocess" it after reading from a - peer. These processing steps might include encryption, - compression, applying checksums or any number of other actions. -<P> -In this tutorial a Protocol_Stream object is created to encrypt and - compress* data being sent between peers. Both client and server - applications are presented as well. I present the application -level code first and then go into the details of the protocol stream -and it's helper objects. If the stream stuff in the application logic -is confusing then just read on by and come back to it after the later -discussions. - -<P> -<font size=-1>* Ok, I didn't really implement encryption and - compression objects. I'll leave that as a thought - exercise!</font> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page02.html b/docs/tutorials/015/page02.html deleted file mode 100644 index 4431fc4cf78..00000000000 --- a/docs/tutorials/015/page02.html +++ /dev/null @@ -1,93 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -We'll take a look first at the client application. As usual, our goal - is to keep the main() application as simple as possible and - delegate the tricky stuff to another object. - -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>/* The Client object will implement the nasty details of connecting to - communicating with the server -*/</font> -<font color=blue>#include</font> "<font color=green>Client_i.h</font>" - -int main(int argc, char *argv[]) -{ - <font color=red>// How many messages will we send?</font> - int mcount = argc > 1 ? <font color=#008888>ACE_OS::atoi</font>(argv[1]) : 3; - - <font color=red>// Construct a Client with our desired endpoint.</font> - Client client(ACE_DEFAULT_SERVER_PORT,ACE_DEFAULT_SERVER_HOST); - - <font color=red>// Attempt to open the connection to the server.</font> - if( client.open() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Client::open</font>()</font>"), -1); - } - - <font color=red>// Send a few messages to the server and get some responses...</font> - for( int i = 0 ; i < mcount ; ++i ) - { - <font color=red>// Since we'll be using a Protocol Stream (even though we</font> - <font color=red>// don't know that at this level) we require the use of</font> - <font color=red>// ACE_Message_Block objects to send/receive data.</font> - ACE_Message_Block * message = new ACE_Message_Block( 128 ); - - <font color=red>// Construct a silly message to send to the server.</font> - <font color=red>// Notice that we're careful to add one to the strlen() so </font> - <font color=red>// that we also send the end-of-string NULL character.</font> - <font color=#008888>ACE_OS::sprintf</font> (message->wr_ptr (), "<font color=green>This is message %d.</font>", i); - message->wr_ptr (strlen (message->rd_ptr ())+1); - - <font color=red>// client will take ownership of the message block so that </font> - <font color=red>// we don't have to remember to release(). We *do* have</font> - <font color=red>// to remember not to use it after put() since it may be</font> - <font color=red>// released almost immediately.</font> - client.put( message ); - - ACE_Message_Block * response; - - <font color=red>// get() takes an ACE_Message_Block pointer reference. We then</font> - <font color=red>// assume ownership of it and must release() when we're done.</font> - if( client.get( response ) == -1 ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Failed to get response from server\n</font>" )); - break; - } - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) The server's response: (%s)\n</font>", - response->rd_ptr())); - - <font color=red>// Now that we're through with the response we have to</font> - <font color=red>// release() it to avoid memory leaks.</font> - response->release(); - } - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shutting down the stream\n</font>" )); - - <font color=red>// Before we exit, it's a good idea to properly close() the connection.</font> - if( client.close() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Client::close</font>()</font>"), -1); - } - - return(0); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page03.html b/docs/tutorials/015/page03.html deleted file mode 100644 index 76f57fab17f..00000000000 --- a/docs/tutorials/015/page03.html +++ /dev/null @@ -1,98 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Client object is designed to hide all of the messy connection - logic from it's users. It also provides put/get methods for - sending data to the server and receiving the server's response. - Note the Protocol_Stream member that will take care of - converting and sending/receiving the data. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>CLIENT_H</font> -<font color=blue>#define</font> <font color=purple>CLIENT_H</font> - -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>Protocol_Stream.h</font>" - -class ACE_Message_Block; - -<font color=red>/* Hide the details of connection and protocol-conformance from the - application-level logic. -*/</font> -class Client -{ -public: - <font color=red>// Provide the server information when constructing the</font> - <font color=red>// object. This could (and probably should) be moved to the</font> - <font color=red>// open() method.</font> - Client( u_short _port, const char * _server ); - - <font color=red>// Cleanup...</font> - ~Client(void); - - <font color=red>// Open the connection to the server.</font> - int open(void); - - <font color=red>// Close the connection to the server. Be sure to do this</font> - <font color=red>// before you let the Client go out of scope.</font> - int close(void); - - <font color=red>// Put a message to the server. The Client assumes ownership</font> - <font color=red>// of _message at that point and will release() it when done.</font> - <font color=red>// Do not use _message after passing it to put().</font> - int put( ACE_Message_Block * _message ); - - <font color=red>// Get a response from the server. The caller becomes the</font> - <font color=red>// owner of _response after this call and is responsible for</font> - <font color=red>// invoking release() when done.</font> - int get( ACE_Message_Block * & _response ); - -private: - <font color=red>// Protocol_Stream hides the protocol conformance details from</font> - <font color=red>// us.</font> - Protocol_Stream stream_; - - <font color=red>// We create a connection on the peer_ and then pass ownership</font> - <font color=red>// of it to the protocol stream.</font> - ACE_SOCK_Stream peer_; - - <font color=red>// Endpoing information saved by the constructor for use by open().</font> - u_short port_; - const char * server_; - - <font color=red>// Accessors for the complex member variables.</font> - - Protocol_Stream & stream(void) - { - return this->stream_; - } - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } -}; - -<font color=blue>#endif</font> <font color=red>// CLIENT_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page04.html b/docs/tutorials/015/page04.html deleted file mode 100644 index 866fede9c52..00000000000 --- a/docs/tutorials/015/page04.html +++ /dev/null @@ -1,95 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The implementation of the Client object. Only the open() method - really does any work. The other methods simply delegate their - function to the Protocol_Stream. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Client_i.h</font>" -<font color=blue>#include</font> "<font color=green>ace/Message_Block.h</font>" -<font color=blue>#include</font> "<font color=green>ace/INET_Addr.h</font>" -<font color=blue>#include</font> "<font color=green>ace/SOCK_Connector.h</font>" - -<font color=red>// Simple constructor just remembers the endpoint information for use by open.</font> -<font color=#008888>Client::Client</font>( u_short _port, const char * _server) - : port_(_port), server_(_server) -{ - ; -} - -<font color=red>/* Do nothing. This should probably call close() if we can make sure - that it's OK to close() multiple times. -*/</font> -<font color=#008888>Client::~Client</font>(void) -{ - ; -} - -<font color=red>/* Open the connection to the server. This is traditional ACE. We - simply construct an endpoint and use a connector to establish the - link. -*/</font> -int <font color=#008888>Client::open</font>( void ) -{ - ACE_INET_Addr addr(port_,server_); - ACE_SOCK_Connector con; - - if( con.connect(peer(),addr) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>ACE_SOCK_Connector::connect</font>()</font>"), -1); - } - - <font color=red>// Something new here... We have to use the protocol stream</font> - <font color=red>// to ensure that our data is in the correct format when</font> - <font color=red>// received by the server. Thus, we open the stream and</font> - <font color=red>// transfer ownership of the peer.</font> - return stream().open( peer() ); -} - -<font color=red>// The remainder of the functions just delegate to the stream.</font> - -int <font color=#008888>Client::close</font>( void ) -{ - return stream().close(); -} - -int <font color=#008888>Client::put</font>( ACE_Message_Block * _message ) -{ - return stream().put(_message,0); -} - -int <font color=#008888>Client::get</font>( ACE_Message_Block * & _response ) -{ - return stream().get(_response); -} -</PRE> -<HR> -<P> -Ok, that's it for the client. We've seen a very simple main() - followed by an equally simple Client object. -<P> -For a quick look back: -<UL> -<LI><A HREF="client.cpp">client.cpp</A> -<LI><A HREF="Client.h">Client.h</A> -<LI><A HREF="Client.cpp">Client.cpp</A> -</UL> -<P> -Now we'll move on and examine the server counter-part of our client. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page05.html b/docs/tutorials/015/page05.html deleted file mode 100644 index d13aaa80476..00000000000 --- a/docs/tutorials/015/page05.html +++ /dev/null @@ -1,71 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Like the client, we want to keep the main() part of our server code as - simple as possible. This is done by putting most of the work - into the Handler object that will deal with client connections. -From the looks of the code below, I think we've been successful in our -simplification. -<HR> - -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Server_i.h</font>" - -<font color=red>// A signal handler that will close the server object</font> -extern "<font color=green>C</font>" void handler (int) -{ - <font color=#008888>Server::close</font>(); -} - -int main (int, char **) -{ - <font color=red>// The server object that abstracts away all of difficult parts.</font> - Server server; - - <font color=red>// Attempt to open the server. Like all good ACE-based</font> - <font color=red>// objects, we'll get -1 on failure.</font> - if( server.open() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>server.open()</font>"), -1); - } - - <font color=red>// Install a signal handler for ^C so that we can exit gracefully</font> - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - <font color=red>// Run the server's main loop until we're interrupted</font> - if( server.run() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>server.run()</font>"), -1); - } - - return 0; -} - -<font color=red>/* These explicit instantiations were taken from an earlier tutorial. - Your compiler may require others as well. -*/</font> -<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>) -template class ACE_Acceptor <Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Acceptor <Handler, ACE_SOCK_ACCEPTOR> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font> - -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page06.html b/docs/tutorials/015/page06.html deleted file mode 100644 index 5fc8f8eca24..00000000000 --- a/docs/tutorials/015/page06.html +++ /dev/null @@ -1,79 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Server object exists in order simplify the -main() application level. To that end, it hides the details of -creating an acceptor and managing the reactor. -<P> -The static close() method available for a signal handler as you saw on -the previous page. Of course the assumption here is that there would -only be one Server instance but since you can't provide a TCP/IP port, -that's probably a valid assumption! -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>SERVER_H</font> -<font color=blue>#define</font> <font color=purple>SERVER_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Acceptor.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>ace/SOCK_Acceptor.h</font>" -<font color=blue>#include</font> "<font color=green>Handler.h</font>" - -<font color=red>/* Anytime I have templates I try to remember to create a typedef for - the parameterized object. It makes for much less typing later! -*/</font> -typedef ACE_Acceptor < Handler, ACE_SOCK_ACCEPTOR > Acceptor; - -class Server -{ -public: - <font color=red>// Our simple constructor takes no parameters. To make the</font> - <font color=red>// server a bit more useful, you may want to pass in the</font> - <font color=red>// TCP/IP port to be used by the acceptor.</font> - Server(void); - ~Server(void); - - <font color=red>// Open the server for business</font> - int open(void); - - <font color=red>// Close all server instances by setting the finished_ flag.</font> - <font color=red>// Actually, the way this class is written, you can only have</font> - <font color=red>// one instance.</font> - static int close(void); - - <font color=red>// Run the server's main loop. The use of the gloabl</font> - <font color=red>// ACE_Reactor by this method is what limits us to one Server</font> - <font color=red>// instance.</font> - int run(void); - -private: - <font color=red>// This will accept client connection requests and instantiate</font> - <font color=red>// a Handler object for each new connection.</font> - Acceptor acceptor_; - - <font color=red>// Our shutdown flag</font> - static sig_atomic_t finished_; -}; - -<font color=blue>#endif</font> <font color=red>// SERVER_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page07.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page07.html b/docs/tutorials/015/page07.html deleted file mode 100644 index 3adcdad99de..00000000000 --- a/docs/tutorials/015/page07.html +++ /dev/null @@ -1,96 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And now the implementation of Server. This is actually just the -main() code from a previous tutorial broken into appropriate method -calls. It may seem silly to do this rather than keeping the stuff in -main() but you'll find that you have less trouble enhancing an -application when you take this sort of approach. -<HR> - -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Server_i.h</font>" - -<font color=red>/* We have to allocate space for our static finished_ flag. We also - initialize it to 'false' so that we don't exit immediately. -*/</font> -sig_atomic_t <font color=#008888>Server::finished_</font> = 0; - -<font color=red>/* The simple constructor and destructor don't do anything but give us - a place to expand in the future if we want. -*/</font> -<font color=#008888>Server::Server</font>(void) -{ - ; -} - -<font color=#008888>Server::~Server</font>(void) -{ - ; -} - -<font color=red>/* Opening the server is as simple as opening the acceptor with the - default ACE_Reactor instance. If we want to allow multiple - instances of Server objects then we should have an ACE_Reactor - member variable that we can register with. -*/</font> -int <font color=#008888>Server::open</font>(void) -{ - if (acceptor_.open (ACE_INET_Addr (ACE_DEFAULT_SERVER_PORT), <font color=#008888>ACE_Reactor::instance</font>()) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>open</font>"), -1); - - return(0); -} - -<font color=red>/* Running the server just means that we execute the basic event - loop for the reactor. Again, if we had a private reactor then we - could have multiple server's in their run() method. -*/</font> -int <font color=#008888>Server::run</font>(void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) starting up server daemon\n</font>")); - - ACE_Time_Value timeout(2); - - <font color=red>// Here's the basic event loop. I have a 2-second timeout on</font> - <font color=red>// the handle_events() so that we don't have to wait too long</font> - <font color=red>// when we set the finished_ flag.</font> - while (!finished_) - { - <font color=#008888>ACE_Reactor::instance</font>()->handle_events (&timeout); - } - - <font color=red>// Close the acceptor when we're done. This may be handled by </font> - <font color=red>// the framework but it's good practice to be explicit about things.</font> - acceptor_.close(); - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) shutting down server daemon\n</font>")); - - return 0; -} - -<font color=red>/* The close() method simply sets the finished_ flag so that run() - will leave the event loop and exit. -*/</font> -int <font color=#008888>Server::close</font>(void) -{ - finished_ = 1; - return(0); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page08.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page08.html b/docs/tutorials/015/page08.html deleted file mode 100644 index ffa7d9c63c9..00000000000 --- a/docs/tutorials/015/page08.html +++ /dev/null @@ -1,94 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Handler object is our event handler. You can use either -ACE_Event_Handler or ACE_Svc_Handler<> for the baseclass. I generally -prefer the latter since it takes care of some housekeeping that I -would otherwise be responsible for. -<P> -The class declaration is taken almost exactly from a previous -tutorial. A good design will have a simple handler object that will -collect data from the peer and pass it along to another object for -processing. Again, keep it simple and delegate authority. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>HANDLER_H</font> -<font color=blue>#define</font> <font color=purple>HANDLER_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Svc_Handler.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" -<font color=blue>#include</font> "<font color=green>Protocol_Stream.h</font>" - -<font color=red>/* Just your basic event handler. We use ACE_Svc_Handler<> as a - baseclass so that it can maintain the peer() and other details for - us. We're not going to activate() this object, so we can get away - with the NULL synch choice. -*/</font> -class Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > -{ -public: - - Handler(void); - ~Handler(void); - - <font color=red>// Called by the acceptor when we're created in response to a</font> - <font color=red>// client connection.</font> - int open (void *); - - <font color=red>// Called when it's time for us to be deleted. We take care</font> - <font color=red>// of removing ourselves from the reactor and shutting down</font> - <font color=red>// the peer() connectin.</font> - void destroy (void); - - <font color=red>// Called when it's time for us to go away. There are subtle</font> - <font color=red>// differences between destroy() and close() so don't try to</font> - <font color=red>// use either for all cases.</font> - int close (u_long); - -protected: - - <font color=red>// Respond to peer() activity.</font> - int handle_input (ACE_HANDLE); - - <font color=red>// This will be called when handle_input() returns a failure</font> - <font color=red>// code. That's our signal that it's time to begin the</font> - <font color=red>// shutdown process.</font> - int handle_close(ACE_HANDLE, ACE_Reactor_Mask _mask); - -private: - - <font color=red>// Like the Client, we have to abide by the protocol</font> - <font color=red>// requirements. We use a local Protocol_Stream object to</font> - <font color=red>// take care of those details. For us, I/O then just becomes</font> - <font color=red>// a matter of interacting with the stream.</font> - Protocol_Stream stream_; - - Protocol_Stream & stream(void) - { - return this->stream_; - } -}; - -<font color=blue>#endif</font> <font color=red>// HANDLER_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page09.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page09.html b/docs/tutorials/015/page09.html deleted file mode 100644 index cd3961df766..00000000000 --- a/docs/tutorials/015/page09.html +++ /dev/null @@ -1,225 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Like any other event handler, the handle_input() method will be -responsible for getting data from the peer() and doing something with -it. In this case, we have a Protocol_Stream to deal with. We'll use -the stream for the actual I/O but we are ultimately responsible for -processing the data from the peer. To do that, we've created a -Handler_Task that fits within the Protocol_Stream framework to process -data that has been received. Handler::handle_input() will tell the stream that -it's time to read data and that data will eventually show up at -Handler_Task::recv() where we'll process it as required by our -application logic. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Handler.h</font>" -<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>" - -<font color=red>/* The Protocol_Stream gives us the option to insert a Protocol_Task - to process data received by the stream. We'll get into the details - more when we talk about the stream in detail. For now it's enough - to know that <font color=#008888>Handler_Task::recv</font>() will be invoked by the stream - after data from the client has been received and processed (eg -- - decrypted, uncompressed, and whatever else the protocol requires.) -*/</font> -class Handler_Task : public Protocol_Task -{ -public: - - <font color=red>// Typical...</font> - typedef Protocol_Task inherited; - - <font color=red>// Simple...</font> - Handler_Task(void); - ~Handler_Task(void); - -protected: - - <font color=red>// recv() is invoked after received data has been fully</font> - <font color=red>// processed by the protocol rules. Data processing typically </font> - <font color=red>// done in handle_input() can then be done here.</font> - int recv(ACE_Message_Block * message, - ACE_Time_Value *timeout = 0); -}; - -<font color=#008888>Handler::Handler</font>(void) -{ - ; -} - -<font color=#008888>Handler::~Handler</font>(void) -{ - ; -} - -<font color=red>/* The Acceptor will open() us once the peer() connection is - established. There are a couple of things we have to do here - before we're ready to receive data from the client. -*/</font> -int <font color=#008888>Handler::open</font> (void *) -{ - ACE_INET_Addr addr; - - <font color=red>// Make sure that we can get the peer's address. If we can't</font> - <font color=red>// then there may be a network error or something else that</font> - <font color=red>// will prevent communicating with the client. This is</font> - <font color=red>// something you'll want to do in every event handler you create.</font> - if (this->peer ().get_remote_addr (addr) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) can't get remote addr\n</font>"), -1); - - <font color=red>// Announce the client</font> - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) connected with %s\n</font>", addr.get_host_name() )); - - <font color=red>// Here's the first new twist to the old event handler.</font> - <font color=red>// Before we can use the Protocol_Stream to communicate with</font> - <font color=red>// the peer, we must open() it. We provide the stream with</font> - <font color=red>// the peer() so that it will have a valid socket on which to</font> - <font color=red>// read client requests and send our responses. We also</font> - <font color=red>// provide a Handler_Task instance that will ultimately be</font> - <font color=red>// responsible for processing any client data we receive.</font> - int rval = stream().open( this->peer(), new Handler_Task() ); - - <font color=red>// Of course, we have to account for the chance that the</font> - <font color=red>// stream's open() may fail.</font> - if( rval == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) can't open the protocol stream.\n</font>"), -1); - } - - <font color=red>// Now that we know the client is valid and that the stream is </font> - <font color=red>// ready for business we can register with the gloabl reactor</font> - <font color=red>// instance. Here again is an opportunity for improvement if</font> - <font color=red>// we expect to have mulitple Server object instances.</font> - if (<font color=#008888>ACE_Reactor::instance</font>()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) can't register with reactor\n</font>"), -1); - - return rval; -} - -<font color=red>/* This is a fairly typical destroy() method that can be shared by - both close() and handle_close(). -*/</font> -void <font color=#008888>Handler::destroy</font> (void) -{ - <font color=#008888>ACE_Reactor::instance</font>()->remove_handler(this,ACE_Event_Handler::READ_MASK|ACE_Event_Handler::DONT_CALL); - - this->peer ().close (); - - delete this; -} - -<font color=red>/* In this simple application we just forward the close() and - handle_close() requests right on to the destroy() method. -*/</font> - -int <font color=#008888>Handler::close</font> (u_long) -{ - this->destroy (); - return 0; -} - -int <font color=#008888>Handler::handle_close</font>(ACE_HANDLE, ACE_Reactor_Mask _mask) -{ - this->destroy(); - return 0; -} - -<font color=red>/* Unlike a "<font color=green>traditional</font>" handle_input() ours is very simple. Because - of the use of the protocol stream, we delegate the read function to - the stream's get() and rely on our Handler_Task to do the real work. -*/</font> -int <font color=#008888>Handler::handle_input</font> (ACE_HANDLE) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) Activity from client\n</font>" )); - - <font color=red>// This will cause a blocking read from the peer(). The data</font> - <font color=red>// will then be pushed through the protocol stream.</font> - if( stream().get( ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) can't get data from protocol stream\n</font>"), -1); - } - - return 0; -} - -<font color=red>/* A Protocol_Task is derived from ACE_Task and has the option of - running in one or more threads. I've chosen here to construct the - baseclass with no threads but it should work just fine with one or - more if you need. Unless you're sharing the Handler_Task with - several peers, however, you're probably just wasting a thread to - activate it. On the other hand, if your reactor is running in a - single thread (as in this example) then you can easily implement - thread-per-connectin concurrency by giving the baseclass one thread. -*/</font> -<font color=#008888>Handler_Task::Handler_Task</font>(void) - : inherited(0) -{ - ; -} - -<font color=#008888>Handler_Task::~Handler_Task</font>(void) -{ - ; -} - -<font color=red>/* When installed into the protocol stream, the Handler_Task's recv() - method will be called when data is ready for processing. - */</font> -int <font color=#008888>Handler_Task::recv</font>(ACE_Message_Block * message, - ACE_Time_Value *timeout ) -{ - <font color=red>// Announce the request we got from the client</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) <font color=#008888>Handler_Task::recv</font>() got (%s)\n</font>", message->rd_ptr() )); - - <font color=red>// Create a response message to send to the client</font> - ACE_Message_Block * response = new ACE_Message_Block( 128 ); - - <font color=red>// Nothing very original about this I'm afraid...</font> - <font color=#008888>ACE_OS::sprintf</font>( response->wr_ptr(), "<font color=green>You Said: (%s)</font>", message->rd_ptr() ); - response->wr_ptr( strlen(response->wr_ptr())+1 ); - - <font color=red>// Release the original message block now that we're through</font> - <font color=red>// "<font color=green>processing</font>" it.</font> - message->release(); - - <font color=red>// Turn the message around and send it back down the Stream.</font> - <font color=red>// In other words, we invoke the put() method on the</font> - <font color=red>// Protocol_Stream without having to have a direct reference</font> - <font color=red>// to the stream object.</font> - return this->reply( response, timeout ); -} -</PRE> -<HR> -<P> -That's it for the server-specific code. I think I've been fairly -successful in keeping it simple and to the point. There are a couple -of places where the as-yet-undescribed Protocol_Stream pops up and may -cause confusion. We're going to discuss that mystery now but before -we do here's the list of server files if you want to review: - -<UL> -<LI><A HREF="server.cpp">server.cpp</A> -<LI><A HREF="Server.h">Server.h</A> -<LI><A HREF="Server.cpp">Server.cpp</A> -<LI><A HREF="Handler.h">Handler.h</A> -<LI><A HREF="Handler.cpp">Handler.cpp</A> -<LI><A HREF="Makefile.server">Server Makefile</A> -</UL> -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page10.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page10.html b/docs/tutorials/015/page10.html deleted file mode 100644 index 476dfe3c7a0..00000000000 --- a/docs/tutorials/015/page10.html +++ /dev/null @@ -1,126 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And so finally we come to the Protocol_Stream. That, after all, is -the focus of the entire tutorial but it took us half of the day to get -here! -<P> -The Protocol_Stream uses an ACE_Stream to move an ACE_Message_Block -through a series of tasks. Each task in the stream is responsible for -performing some operation on the data in the message block. That is -the nature of a protocol stream (or "stack" if you prefer). In this -stream, the data is compressed and encrypted* on its way between -peers. We also allow users of the stream to install a reader task to -handle data that percolates up from the peer. As you saw a page or -two ago, this is most useful for a server. - -<P> -<font size=-1>*Again, I just pretend to do these things. It would -take another day or two to go through any sort of reasonable -encryption or compression!</font> -<P> -Before we get into the code, here's a picture that's shows what's -going on here. -<P><center><img src="stream.gif"></center></p> -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>PROTOCOL_STREAM_H</font> -<font color=blue>#define</font> <font color=purple>PROTOCOL_STREAM_H</font> - -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<font color=green>ace/Stream.h</font>" - -<font color=red>// Shorthand for the stream.</font> -typedef ACE_Stream<ACE_MT_SYNCH> Stream; - -<font color=red>// Forward references to cut down on the number of <font color=blue>#include</font>s</font> -class ACE_Message_Block; -class Recv; -class Protocol_Task; - -<font color=red>/* The Protocol_Stream provides a tidy interface to an ACE_Stream - setup to process a data block through a series of protocol stages. -*/</font> -class Protocol_Stream -{ -public: - Protocol_Stream(void); - ~Protocol_Stream(void); - - <font color=red>// Provide the stream with an ACE_SOCK_Stream on which it can</font> - <font color=red>// communicate. If _reader is non-null, it will be added as</font> - <font color=red>// the reader task just below the stream head so that it can</font> - <font color=red>// process data read from the peer.</font> - int open( ACE_SOCK_Stream & _peer, Protocol_Task * _reader = 0 ); - - <font color=red>// Close the stream. All of the tasks & modules will also be closed.</font> - int close(void); - - <font color=red>// putting data onto the stream will pass it through all</font> - <font color=red>// protocol levels and send it to the peer.</font> - int put( ACE_Message_Block * & _message, ACE_Time_Value * - _timeout = 0 ); - - <font color=red>// get will cause the Recv task (at the tail of the stream) to</font> - <font color=red>// read some data from the peer and pass it upstream. The</font> - <font color=red>// message block is then taken from the stream reader task's</font> - <font color=red>// message queue.</font> - int get( ACE_Message_Block * & _response, ACE_Time_Value * - _timeout = 0 ); - - <font color=red>// Tell the Recv task to read some data and send it upstream.</font> - <font color=red>// The data will pass through the protocol tasks and be queued</font> - <font color=red>// into the stream head reader task's message queue. If</font> - <font color=red>// you've installed a _reader in open() then that task's</font> - <font color=red>// recv() method will see the message and may consume it</font> - <font color=red>// instead of passing it to the stream head for queueing.</font> - int get(void); - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } - -private: - <font color=red>// Our peer connection</font> - ACE_SOCK_Stream peer_; - - <font color=red>// The stream managing the various protocol tasks</font> - Stream stream_; - - <font color=red>// A task which is capable of receiving data on a socket.</font> - <font color=red>// Note that this is only useful by client-side applications.</font> - Recv * recv_; - - Stream & stream(void) - { - return this->stream_; - } - - <font color=red>// Install the protocol tasks into the stream.</font> - int open(void); -}; - -<font color=blue>#endif</font> <font color=red>// PROTOCOL_STREAM_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page11.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page11.html b/docs/tutorials/015/page11.html deleted file mode 100644 index 7b5757c1ef4..00000000000 --- a/docs/tutorials/015/page11.html +++ /dev/null @@ -1,195 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And now the implementation of the Protocol_Stream. There are more -lines of code here than we've seen so far but it still isn't -complicated. The basic idea is to construct the ACE_Stream with our -set of protocol objects that will manipulate the data. Our primary -concern in this file is to get everything in the correct order! -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Protocol_Stream.h</font>" -<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>" - -<font color=blue>#include</font> "<font color=green>Xmit.h</font>" -<font color=blue>#include</font> "<font color=green>Recv.h</font>" - -<font color=blue>#include</font> "<font color=green>Compressor.h</font>" -<font color=blue>#include</font> "<font color=green>Crypt.h</font>" - -<font color=blue>#include</font> "<font color=green>ace/Stream_Modules.h</font>" - -<font color=red>/* You can choose at compile time to include/exclude the protocol - pieces. -*/</font> -<font color=blue>#define</font> <font color=purple>ENABLE_COMPRESSION</font> -<font color=blue>#define</font> <font color=purple>ENABLE_ENCRYPTION</font> - -<font color=red>// The usual typedefs to make things easier to type.</font> -typedef ACE_Module<ACE_MT_SYNCH> Module; -typedef ACE_Thru_Task<ACE_MT_SYNCH> Thru_Task; - -<font color=red>/* Do-nothing constructor and destructor - */</font> - -<font color=#008888>Protocol_Stream::Protocol_Stream</font>( void ) -{ - ; -} - -<font color=#008888>Protocol_Stream::~Protocol_Stream</font>( void ) -{ - ; -} - -<font color=red>/* Even opening the stream is rather simple. The important thing to - rememer is that the modules you push onto the stream first will be - at the tail (eg -- most downstream) end of things when you're - done. - */</font> -int <font color=#008888>Protocol_Stream::open</font>( ACE_SOCK_Stream & _peer, Protocol_Task * _reader ) -{ - <font color=red>// Initialize our peer() to read/write the socket we're given</font> - peer_.set_handle( _peer.get_handle() ); - - <font color=red>// Construct (and remember) the Recv object so that we can</font> - <font color=red>// read from the peer().</font> - recv_ = new Recv( peer() ); - - <font color=red>// Add the transmit and receive tasks to the head of the</font> - <font color=red>// stream. As we add more modules these will get pushed</font> - <font color=red>// downstream and end up nearest the tail by the time we're</font> - <font color=red>// done.</font> - if( stream().push( new Module( "<font color=green>Xmit/Recv</font>", new Xmit( peer() ), recv_ ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( xmit/recv )</font>"), -1); - } - - <font color=red>// Add any other protocol tasks to the stream. Each one is</font> - <font color=red>// added at the head. The net result is that Xmit/Recv are at </font> - <font color=red>// the tail.</font> - if( this->open() == -1 ) - { - return(-1); - } - - <font color=red>// If a reader task was provided then push that in as the</font> - <font color=red>// upstream side of the next-to-head module. Any data read</font> - <font color=red>// from the peer() will be sent through here last. Server</font> - <font color=red>// applications will typically use this task to do the actual</font> - <font color=red>// processing of data.</font> - <font color=red>// Note the use of Thru_Task. Since a module must always have </font> - <font color=red>// a pair of tasks we use this on the writter side as a no-op.</font> - if( _reader ) - { - if( stream().push( new Module( "<font color=green>Reader</font>", new Thru_Task(), _reader ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( reader )</font>"), -1); - } - } - - return(0); -} - -<font color=red>/* Add the necessary protocol objects to the stream. The way we're - pushing things on we will encrypt the data before compressing it. -*/</font> -int <font color=#008888>Protocol_Stream::open</font>(void) -{ -<font color=blue>#if defined</font>(<font color=purple>ENABLE_COMPRESSION</font>) - if( stream().push( new Module( "<font color=green>compress</font>", new Compressor(), new Compressor() ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( comprssor )</font>"), -1); - } -<font color=blue>#endif</font> <font color=red>// ENABLE_COMPRESSION</font> - -<font color=blue>#if defined</font>(<font color=purple>ENABLE_ENCRYPTION</font>) - if( stream().push( new Module( "<font color=green>crypt</font>", new Crypt(), new Crypt() ) ) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( crypt )</font>"), -1); - } -<font color=blue>#endif</font> <font color=red>// ENABLE_ENCRYPTION</font> - return( 0 ); -} - -<font color=red>// Closing the Protocol_Stream is as simple as closing the ACE_Stream.</font> -int <font color=#008888>Protocol_Stream::close</font>(void) -{ - return stream().close(); -} - -<font color=red>// Simply pass the data directly to the ACE_Stream.</font> -int <font color=#008888>Protocol_Stream::put</font>(ACE_Message_Block * & _message, ACE_Time_Value * _timeout ) -{ - return stream().put(_message,_timeout); -} - -<font color=red>/* Tell the Recv module to read some data from the peer and pass it - upstream. Servers will typically use this method in a - handle_input() method to tell the stream to get a client's request. -*/</font> -int <font color=#008888>Protocol_Stream::get</font>(void) -{ - <font color=red>// If there is no Recv module, we're in big trouble!</font> - if( ! recv_ ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) No Recv object!\n</font>"), -1); - } - - <font color=red>// This tells the Recv module to go to it's peer() and read</font> - <font color=red>// some data. Once read, that data will be pushed upstream.</font> - <font color=red>// If there is a reader object then it will have a chance to</font> - <font color=red>// process the data. If not, the received data will be</font> - <font color=red>// available in the message queue of the stream head's reader</font> - <font color=red>// object (eg -- stream().head()->reader()->msg_queue()) and</font> - <font color=red>// can be read with our other get() method below.</font> - if( recv_->get() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot queue read request\n</font>"), -1); - } - - <font color=red>// For flexibility I've added an error() method to tell us if</font> - <font color=red>// something bad has happened to the Recv object.</font> - if( recv_->error() ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Recv object error!\n</font>"), -1); - } - - return(0); -} - -<font color=red>/* Take a message block off of the stream head reader's message - queue. If the queue is empty, use get() to read from the peer. - This is most often used by client applications. Servers will - generaly insert a reader that will prevent the data from getting - all the way upstream to the head. -*/</font> -int <font color=#008888>Protocol_Stream::get</font>(ACE_Message_Block * & _response, ACE_Time_Value * _timeout ) -{ - if( stream().head()->reader()->msg_queue()->is_empty() ) - { - if( this->get() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot get data into the stream.\n</font>"), -1); - } - } - - return stream().head()->reader()->getq(_response,_timeout); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page12.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page12.html b/docs/tutorials/015/page12.html deleted file mode 100644 index 81528f63c79..00000000000 --- a/docs/tutorials/015/page12.html +++ /dev/null @@ -1,98 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And now the implementation of the Protocol_Stream. There are more -lines of code here than we've seen so far but it still isn't -complicated. The basic idea is to construct the ACE_Stream with our -set of protocol objects that will manipulate the data. Our primary -concern in this file is to get everything in the correct order! -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>PROTOCOL_TASK_H</font> -<font color=blue>#define</font> <font color=purple>PROTOCOL_TASK_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Task.h</font>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -# pragma once -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=red>/* A typical ACE_Task<> derivative that adds a few things appropriate - to protocol stacks. -*/</font> -class Protocol_Task : public ACE_Task<ACE_MT_SYNCH> -{ -public: - - typedef ACE_Task<ACE_MT_SYNCH> inherited; - - <font color=red>// A choice of concurrency strategies is offered by the</font> - <font color=red>// constructor. In most cases it makes sense to set this to</font> - <font color=red>// zero and let things proceed serially. You might have a</font> - <font color=red>// need, however, for some of your tasks to have their own thread.</font> - Protocol_Task( int _thr_count ); - - ~Protocol_Task(void); - - <font color=red>// open() is invoked when the task is inserted into the stream.</font> - virtual int open(void *arg); - - <font color=red>// close() is invoked when the stream is closed (flags will be</font> - <font color=red>// set to '1') and when the svc() method exits (flags will be</font> - <font color=red>// '0').</font> - virtual int close(u_long flags); - - <font color=red>// As data travels through the stream, the put() method of</font> - <font color=red>// each task is invoked to keep the data moving along.</font> - virtual int put(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - <font color=red>// If you choose to activate the task then this method will be</font> - <font color=red>// doing all of the work.</font> - virtual int svc(void); - -protected: - - <font color=red>// Called by put() or svc() as necessary to process a block of</font> - <font color=red>// data.</font> - int process(ACE_Message_Block * message, ACE_Time_Value *timeout); - - <font color=red>// Just let us know if we're active or not.</font> - int is_active(void) - { - return this->thr_count() != 0; - } - - <font color=red>// Tasks on the writter (downstream) side of the stream</font> - <font color=red>// are called upon to send() data that will ultimately go to</font> - <font color=red>// the peer.</font> - virtual int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - <font color=red>// Tasks on the reader (upstream) side will be receiving data</font> - <font color=red>// that came from the peer.</font> - virtual int recv(ACE_Message_Block * message, - ACE_Time_Value *timeout); - -private: - int desired_thr_count_; -}; - -<font color=blue>#endif</font> <font color=red>// PROTOCOL_TASK_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page13.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page13.html b/docs/tutorials/015/page13.html deleted file mode 100644 index 967948e3d16..00000000000 --- a/docs/tutorials/015/page13.html +++ /dev/null @@ -1,170 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Protocol_Task implementation takes care of the open(), close(), -put() and svc() methods so that derivatives can concentrate on the -send() and recv() methods. After a while you find that most -ACE_Task<> derivatives look very similar in the four basic methods and -only need one or two additional to do any real work. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>" - -<font color=red>// Construct the object and remember the thread count.</font> -<font color=#008888>Protocol_Task::Protocol_Task</font>( int _thr_count ) - : desired_thr_count_(_thr_count) -{ -} - -<font color=#008888>Protocol_Task::~Protocol_Task</font>(void) -{ -} - -<font color=red>// Activate the object if necessary.</font> -int <font color=#008888>Protocol_Task::open</font>(void *arg) -{ - ACE_UNUSED_ARG(arg); - - if( desired_thr_count_ ) - { - return this->activate(THR_NEW_LWP, desired_thr_count_); - } - - return(0); -} - -<font color=red>/* When we're being closed by the ACE_Stream and we've got threads to - worry about then we drop a hangup message onto the message queue so - that svc() will go away. Except for the call to is_active(), this - is lifted directly from Tutorial 14. -*/</font> -int <font color=#008888>Protocol_Task::close</font>(u_long flags) -{ - if (flags == 1 && is_active() ) - { - ACE_Message_Block *hangupBlock = new ACE_Message_Block(); - - hangupBlock->msg_type(<font color=#008888>ACE_Message_Block::MB_HANGUP</font>); - - if (this->putq(hangupBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::close</font>() putq</font>"), -1); - } - - hangupBlock->release(); - - return this->wait(); - } - - return 0; -} - -<font color=red>/* The put() method has to make a decision. If we've got threads then - put the unit of work onto the message queue for svc() to deal - with. If not then process() it directly. -*/</font> -int <font color=#008888>Protocol_Task::put</font>(ACE_Message_Block *message,ACE_Time_Value *timeout) -{ - if( is_active() ) - { - return this->putq(message,timeout); - } - - return this->process(message,timeout); -} - -<font color=red>/* svc() is about what you would expect. This is again lifted - directly from Tutorial 14 but with a call to process() for handling - the logic instead of doing the work right here. - */</font> -int <font color=#008888>Protocol_Task::svc</font>(void) -{ - ACE_Message_Block * message; - - while (1) - { - <font color=red>// Get a message</font> - if ( this->getq(message, 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Protocol_Task::svc</font>() getq</font>"), -1); - } - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) <font color=#008888>Protocol_Task::svc</font>() got message\n</font>")); - - <font color=red>// Check for hangup</font> - if (message->msg_type() == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>) { - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) <font color=#008888>Protocol_Task::svc</font>() -- HANGUP block received\n</font>")); - - <font color=red>// Hangup our thread-pool peers (if any)</font> - if (this->putq(message->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Protocol_Task::svc</font>() putq</font>"), -1); - } - - <font color=red>// Leave svc()</font> - break; - } - - <font color=red>// Do some work on the data.</font> - if( this->process(message->duplicate(),0) == -1 ) - { - break; - } - - <font color=red>// Give up the message block before we go get another.</font> - message->release(); - } - - <font color=red>// Give up the message block that caused us to exit the</font> - <font color=red>// while(1) loop.</font> - message->release(); - - return(0); -} - -<font color=red>/* There's nothing really magic about process(). We just decide if - we're moving data upstream or downstream and invoke the appropriate - virtual function to handle it. -*/</font> -int <font color=#008888>Protocol_Task::process</font>(ACE_Message_Block * message, ACE_Time_Value *timeout) -{ - if( this->is_writer() ) - { - return this->send(message,timeout); - } - - return this->recv(message,timeout); -} - -<font color=red>/* We must insist that derivatives provide a meaningful overload for - these methods. It's fairly common for ACE object methods to return - an error when an overload is expected but the method cannot be - safely made pure virtual. - */</font> - -int <font color=#008888>Protocol_Task::send</font>(ACE_Message_Block *message, - ACE_Time_Value *timeout) -{ - return -1; -} - -int <font color=#008888>Protocol_Task::recv</font>(ACE_Message_Block * message, - ACE_Time_Value *timeout) -{ - return -1; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page14.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page14.html b/docs/tutorials/015/page14.html deleted file mode 100644 index 1624577470e..00000000000 --- a/docs/tutorials/015/page14.html +++ /dev/null @@ -1,83 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The implementation of Xmit isn't too complicated. If we choose to -combine it with the Recv task we simply lift the recv() method from -that object and drop it into this one. -<P> -Note that close() must decide if it's being called when the stream is -shutdown or when it's svc() method exits. Since we tell the baseclass -not to use any threads it's a safe bet that flags will always be -non-zero. Still, it's good practice to plan for the future by -checking the value. -<P> -Note also that when we send the data we prefix it with the data size. -This let's our sibling Recv ensure that an entire block is received -together. This can be very important for compression and encryption -processes which typically work better with blocks of data instead of -streams of data. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>XMIT_H</font> -<font color=blue>#define</font> <font color=purple>XMIT_h</font> - -<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>" - -<font color=red>// Forward reference reduces <font color=blue>#include</font> dependencies</font> -class ACE_SOCK_Stream; - -<font color=red>/* A class suitable for sending data to a peer from within an - ACE_Stream. - */</font> -class Xmit : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - <font color=red>// We must be given a valid peer when constructed. Without that</font> - <font color=red>// we don't know who to send data to.</font> - Xmit( ACE_SOCK_Stream & _peer ); - - ~Xmit(void); - - <font color=red>// As you know, close() will be called in a couple of ways by the</font> - <font color=red>// ACE framework. We use that opportunity to terminate the</font> - <font color=red>// connection to the peer.</font> - int close(u_long flags); - -protected: - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } - - <font color=red>// Send the data to the peer. By now it will have been</font> - <font color=red>// completely protocol-ized by other tasks in the stream.</font> - int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - -private: - <font color=red>// A representation of the peer we're talking to.</font> - ACE_SOCK_Stream & peer_; -}; - -<font color=blue>#endif</font> <font color=red>// XMIT_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page15.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page15.html b/docs/tutorials/015/page15.html deleted file mode 100644 index be4d3e464a0..00000000000 --- a/docs/tutorials/015/page15.html +++ /dev/null @@ -1,115 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Recv is the sibling to Xmit. Again, they could be combined into a -single object if you want. -<P> -An ACE_Stream is designed to handle downstream traffic very -well. You put() data into it and it flows along towards the tail. -However, there doesn't seem to be a way to put data in such that it -will travel upstream. To get around that, I've added a get() method -to Recv that will trigger a read on the socket. Recv will then put -the data to the next upstream module and we're on our way. As noted -earlier, that data will eventually show up either in the <i>reader</i> -(if installed on the stream open()) or the stream head reader task's -message queue. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Xmit.h</font>" -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -<font color=red>/* Construct the object with the peer connection and choose not to - activate ourselves into a dedicated thread. You might get some - performance gain by activating but if you really want a - multi-threaded apprroach you should handle that as a separate - issue. Attempting to force threading at this level will likely - cause more trouble than you want to deal with. -*/</font> -<font color=#008888>Xmit::Xmit</font>( ACE_SOCK_Stream & _peer ) - : Protocol_Task(0), peer_(_peer) -{ -} - -<font color=#008888>Xmit::~Xmit</font>(void) -{ -} - -<font color=red>/* Check to see if we're being closed by the stream (flags != 0) or if - we're responding to the exit of our svc() method. -*/</font> -int <font color=#008888>Xmit::close</font>(u_long flags) -{ - <font color=red>// Take care of the baseclass closure.</font> - int rval = <font color=#008888>inherited::close</font>(flags); - - <font color=red>// Only if we're being called at the stream shutdown do we close</font> - <font color=red>// the peer connection. If, for some reason, we were activated</font> - <font color=red>// into one or more threads we wouldn't want to close the pipe</font> - <font color=red>// before all threads had a chance to flush their data.</font> - if( flags ) - { - peer().close(); - } - - return( rval ); -} - -<font color=red>/* Our overload of send() will take care of sending the data to the - peer. -*/</font> -int <font color=#008888>Xmit::send</font>(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - int rval; - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) <font color=#008888>Xmit::send</font>() sending (%s)(%d)\n</font>", message->rd_ptr(), message->length() )); - - <font color=red>/* Since we're going to be sending data that may have been - compressed and encrypted it's probably important for the - receiver to get an entire "<font color=green>block</font>" instead of having a - partial read. - - For that reason, we'll send the length of the message block - (in clear-text) to the peer so that it can then recv_n() - the entire block contents in one read operation. - */</font> - char msize[32]; - sprintf(msize,"<font color=green>%d</font>",message->length()); - - <font color=red>// Be sure we send the end-of-string NULL so that Recv will</font> - <font color=red>// know when to stop assembling the length.</font> - rval = this->peer().send_n( msize, strlen(msize)+1, 0, timeout ); - - if( rval == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Xmit::send</font>() Failed to send message size.</font>"), -1); - } - - <font color=red>/* Now we send the actual data. If you're worried about - network efficiency then you may choose to create one buffer - containing msize and the message data and send it all at - once. - */</font> - rval = this->peer().send_n( message->rd_ptr(), message->length(), 0, timeout ); - - <font color=red>// Release the message block since we're done with it.</font> - message->release(); - - return( rval ); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page16.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page16.html b/docs/tutorials/015/page16.html deleted file mode 100644 index aa57e8fb2da..00000000000 --- a/docs/tutorials/015/page16.html +++ /dev/null @@ -1,85 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Recv implementation is nearly as simple as Xmit. There's -opportunity for error when we get the message size and we have to -manage the lifetime of the tickler but other than that it's pretty -basic stuff. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>RECV_H</font> -<font color=blue>#define</font> <font color=purple>RECV_h</font> - -<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>" - -class ACE_SOCK_Stream; - -<font color=red>/* Get some data from the peer and send it upstream for - de-protocol-ization. -*/</font> -class Recv : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - <font color=red>// Give it someone to talk to...</font> - Recv( ACE_SOCK_Stream & _peer ); - - ~Recv(void); - - <font color=red>// Trigger a read from the socket</font> - int get(void); - - <font color=red>// In some cases it might be easier to check the "<font color=green>state</font>" of the</font> - <font color=red>// Recv object than to rely on return codes filtering back to</font> - <font color=red>// you.</font> - int error(void) - { - return this->error_; - } - -protected: - - ACE_SOCK_Stream & peer(void) - { - return this->peer_; - } - - <font color=red>// The baseclass will trigger this when our get() method is</font> - <font color=red>// called. A message block of the appropriate size is created,</font> - <font color=red>// filled and passed up the stream.</font> - int recv(ACE_Message_Block * message, - ACE_Time_Value *timeout = 0); - -private: - <font color=red>// Our endpoint</font> - ACE_SOCK_Stream & peer_; - - <font color=red>// get() uses a bogus message block to cause the baseclass to</font> - <font color=red>// invoke recv(). To avoid memory thrashing, we create that</font> - <font color=red>// bogus message once and reuse it for the life of Recv.</font> - ACE_Message_Block * tickler_; - - <font color=red>// Our error flag (duh)</font> - int error_; -}; - -<font color=blue>#endif</font> <font color=red>// RECV_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page17.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page17.html b/docs/tutorials/015/page17.html deleted file mode 100644 index 8d3aaf660d0..00000000000 --- a/docs/tutorials/015/page17.html +++ /dev/null @@ -1,106 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -This and the next three pages present the protocol objects that -provide compression and encryption. If you were hoping to -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Recv.h</font>" -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -<font color=red>/* Construct the object with the peer reference and other appropriate - initializations. -*/</font> -<font color=#008888>Recv::Recv</font>( ACE_SOCK_Stream & _peer ) - : Protocol_Task(0), peer_(_peer), error_(0) -{ - <font color=red>// Create the tickler that get() will use to trigger recv()</font> - <font color=red>// through the baseclass. Since we're single-threaded this is</font> - <font color=red>// probably overkill but it makes multi-threading easier if we</font> - <font color=red>// choose to do that.</font> - tickler_ = new ACE_Message_Block(1); -} - -<font color=red>/* Be sure we manage the lifetime of the tickler to prevent a memory - leak. -*/</font> -<font color=#008888>Recv::~Recv</font>(void) -{ - tickler_->release(); -} - -<font color=red>/* By putting the tickler to ourselves we cause things to happen in - the baseclass that will invoke recv(). If we know we're single - threaded we could directly call recv() and be done with it but then - we'd have to do something else if we're multi-threaded. Just let - the baseclass worry about those things! -*/</font> -int <font color=#008888>Recv::get</font>(void) -{ - return this->put( tickler_, 0 ); -} - -int <font color=#008888>Recv::recv</font>(ACE_Message_Block * message, ACE_Time_Value *timeout) -{ - int rval; - - <font color=red>/* Xmit will send us the message length in clear-text. I - assume that will be less than 32-bytes! - */</font> - char msize[32]; - int b = 0; - - <font color=red>/* Read from the socket one byte at a time until we see then - end-of-string NULL character. Since the OS layers (at leas - in Unix) will provide some buffering this isn't as bad as - it may seem at first. - */</font> - do - { - rval = this->peer().recv( &msize[b], 1, timeout ); - if( rval == -1 ) - { - error_ = 1; - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Recv::recv</font>() Failed to get message size.</font>"), -1); - } - } - while( msize[b++] != 0 ); - - int size = <font color=#008888>ACE_OS::atoi</font>(msize); - - <font color=red>// Make a block big enough to contain the data we'll read</font> - message = new ACE_Message_Block( size ); - - <font color=red>// Read the actual message data into our new message block</font> - rval = this->peer().recv_n( message->wr_ptr(), size, 0, timeout ); - - <font color=red>// If we got the data correctly then send it on upstream.</font> - if( rval > 0 ) - { - message->wr_ptr( rval ); - return( this->put_next( message ) ); - } - - <font color=red>// Something bad happend on the recv_n(). Set an error flag</font> - <font color=red>// and return error.</font> - error_ = 1; - - return( -1 ); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page18.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page18.html b/docs/tutorials/015/page18.html deleted file mode 100644 index ef67934b597..00000000000 --- a/docs/tutorials/015/page18.html +++ /dev/null @@ -1,68 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -This and the next three pages present the protocol objects that -provide compression and encryption. If you were hoping to learn the -secrets of compression and encryption then I'm going to disappoint -you. There are some really good libraries out there that do this -stuff though and if anyone wants to integrate one of them into the -tutorial I'll be glad to take it! -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>COMPRESSOR_H</font> -<font color=blue>#define</font> <font color=purple>COMPRESSOR_h</font> - -<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>" - -<font color=red>/* A reallly dumb compression object. (It actually adds 3 bytes to - every message block.) -*/</font> -class Compressor : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - <font color=red>// I've given you the option of creating this task derivative</font> - <font color=red>// with a number of threads. In retro-spect that really isn't</font> - <font color=red>// a good idea. Most client/server systems rely on requests</font> - <font color=red>// and responses happening in a predicatable order. Introduce</font> - <font color=red>// a thread pool and message queue and that ordering goes</font> - <font color=red>// right out the window. In other words: Don't ever use the</font> - <font color=red>// constructor parameter!</font> - Compressor( int _thr_count = 0 ); - - ~Compressor(void); - -protected: - - <font color=red>// This is called when the compressor is on the downstream</font> - <font color=red>// side. We'll take the message, compress it and move it</font> - <font color=red>// along to the next module.</font> - int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - <font color=red>// This one is called on the upstream side. No surprise: we</font> - <font color=red>// decompress the data and send it on up the stream.</font> - int recv(ACE_Message_Block *message, - ACE_Time_Value *timeout); -}; - -<font color=blue>#endif</font> <font color=red>// COMPRESSOR_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page19.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page19.html b/docs/tutorials/015/page19.html deleted file mode 100644 index 049bba13a06..00000000000 --- a/docs/tutorials/015/page19.html +++ /dev/null @@ -1,119 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Here we implement the details of our compression. By having both -compression and decompression in one object it's easier to keep track -of implementation details. Splitting Xmit/Recv like I did will make -things more difficult if something has to change in their interaction. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Compressor.h</font>" -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -<font color=red>/* Construct our baseclass with the proper thread count. I really - should remove this option... - */</font> -<font color=#008888>Compressor::Compressor</font>( int _thr_count ) - : Protocol_Task(_thr_count) -{ - ; -} - -<font color=#008888>Compressor::~Compressor</font>(void) -{ - ; -} - -<font color=red>/* This is where you insert your compression code. Most compressors - want to work on a block of data instead of a byte-stream. - Fortunately the message block has a block that can be compressed. - Take a look at libz for a quick way to add compression to your - apps - */</font> -int <font color=#008888>Compressor::send</font>(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) <font color=#008888>Compressor::send</font>() compressing (%s)\n</font>", message->rd_ptr() )); - - <font color=red>// Create a block to hold the compressed data. I belive libz</font> - <font color=red>// recommends a buffer about 10-20% larger than the source.</font> - <font color=red>// Other libraries/algorithms may have their own quirks.</font> - ACE_Message_Block * compressed = new ACE_Message_Block( message->size() ); - - <font color=red>// Perform a bogus compression algorithm. 'CD' just tells me</font> - <font color=red>// that this is compressed data and when we "<font color=green>decompress</font>" we'll </font> - <font color=red>// look for this signature to validate the data received.</font> - <font color=#008888>ACE_OS::sprintf</font>( compressed->wr_ptr(), "<font color=green>CD:%s</font>", message->rd_ptr() ); - compressed->wr_ptr( strlen(compressed->wr_ptr())+1 ); - - <font color=red>// Send the compressed data down the stream to the next module</font> - this->put_next( compressed ); - - <font color=red>// We're done here.</font> - message->release(); - - return( 0 ); -} - -<font color=red>/* And here's the decompression side. We've written Xmit/Recv so that - we're guaranteed to get an entire block of compressed data. If - we'd used recv() in the Recv object then we might have gotten a - partial block and that may not decompress very nicely. - */</font> -int <font color=#008888>Compressor::recv</font>(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) <font color=#008888>Compress::recv</font>() decompressing (%s)\n</font>", message->rd_ptr() )); - - <font color=red>// Room for the decompressed data. In the real world you</font> - <font color=red>// would probably want to send the original (uncompressed)</font> - <font color=red>// data size in the message. You can predict the maximum</font> - <font color=red>// possible decompression size but it's cheap and easy just to </font> - <font color=red>// send that along. Look again at how I do exacly that</font> - <font color=red>// between Xmit and Recv.</font> - ACE_Message_Block * decompressed = new ACE_Message_Block( message->size() ); - - <font color=red>// Check for our signature. Even when you use a real</font> - <font color=red>// compression algorithm you may want to include your own</font> - <font color=red>// signature so that you can verify the block. It pays to be</font> - <font color=red>// paranoid!</font> - if( <font color=#008888>ACE_OS::strncmp</font>( message->rd_ptr(), "<font color=green>CD:</font>", 3 ) ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Improperly encompressed data.\n</font>" )); - message->release(); - return(-1); - } - - <font color=red>// Skip past the signature before going any further.</font> - message->rd_ptr( 3 ); - - <font color=red>// Perform a bogus decompression algorithm. This is where you </font> - <font color=red>// would feed to libz or your favorite decompressor. (It's</font> - <font color=red>// costly but you could invoke popen() on gzip!)</font> - <font color=#008888>ACE_OS::sprintf</font>( decompressed->wr_ptr(), "<font color=green>%s</font>", message->rd_ptr() ); - decompressed->wr_ptr( strlen(decompressed->wr_ptr())+1 ); - - <font color=red>// Recv the decompressed data down the stream to the next module</font> - this->put_next( decompressed ); - - <font color=red>// We're done here.</font> - message->release(); - - return( 0 ); -} - -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page20.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page20.html b/docs/tutorials/015/page20.html deleted file mode 100644 index 641399cb4e2..00000000000 --- a/docs/tutorials/015/page20.html +++ /dev/null @@ -1,61 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -While I might be able to come up with a competitive compressor, I -don't have a snowball's chance to code up encryption. I'd be better -off piping the data through the standard Unix crypt command. -<P> -So, while I was lazy with Compress, I'm realistic with Crypt. I'll -show you the hooks and entry points and let someone else contribute an -encryptor. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>CRYPT_H</font> -<font color=blue>#define</font> <font color=purple>CRYPT_h</font> - -<font color=blue>#include</font> "<font color=green>Protocol_Task.h</font>" - -<font color=red>/* An interface (adaptor) between your favorite encryption method and - an ACE_Stream. -*/</font> -class Crypt : public Protocol_Task -{ -public: - - typedef Protocol_Task inherited; - - <font color=red>// Again we have the option of multiple threads and again I</font> - <font color=red>// regret tempting folks to use it.</font> - Crypt( int _thr_count = 0 ); - - ~Crypt(void); - -protected: - - <font color=red>// Moving downstream will encrypt the data</font> - int send(ACE_Message_Block *message, - ACE_Time_Value *timeout); - - <font color=red>// And moving upstream will decrypt it.</font> - int recv(ACE_Message_Block *message, - ACE_Time_Value *timeout); -}; - -<font color=blue>#endif</font> <font color=red>// CRYPT_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page21.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page21.html b/docs/tutorials/015/page21.html deleted file mode 100644 index 5c7fc54eb27..00000000000 --- a/docs/tutorials/015/page21.html +++ /dev/null @@ -1,99 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The encryption implementation isn't any smarter than that of the -compressor. Still, the hooks are there for you to insert your -favorite library. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Crypt.h</font>" -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -<font color=red>/* The expected constructor... - */</font> -<font color=#008888>Crypt::Crypt</font>( int _thr_count ) - : Protocol_Task(_thr_count) -{ -} - -<font color=#008888>Crypt::~Crypt</font>(void) -{ -} - -<font color=red>/* To send the data we'll apply a signature and encryption. - */</font> -int <font color=#008888>Crypt::send</font>(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) <font color=#008888>Crypt::send</font>() encrypting (%s)\n</font>", message->rd_ptr() )); - - <font color=red>// I suspect that some encryptors might change the data size.</font> - <font color=red>// It probably isn't safe to create a same-size destination buffer.</font> - ACE_Message_Block * encrypted = new ACE_Message_Block( message->size() ); - - <font color=red>// Perform a bogus encryption algorithm and add our safety</font> - <font color=red>// signature. Adding the original data size is also probably</font> - <font color=red>// a good idea that I haven't encorporated here.</font> - <font color=#008888>ACE_OS::sprintf</font>( encrypted->wr_ptr(), "<font color=green>ED:%s</font>", message->rd_ptr() ); - encrypted->wr_ptr( strlen(encrypted->wr_ptr())+1 ); - - <font color=red>// Send the encrypted data down the stream to the next module</font> - this->put_next( encrypted ); - - <font color=red>// We're done here.</font> - message->release(); - - return( 0 ); -} - -<font color=red>/* The upstream movement requires that we decrypt what the peer has - given us. -*/</font> -int <font color=#008888>Crypt::recv</font>(ACE_Message_Block *message, ACE_Time_Value *timeout) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) <font color=#008888>Crypt::recv</font>() decrypting (%s)\n</font>", message->rd_ptr() )); - - <font color=red>// Create a destination for the decrypted data. The same</font> - <font color=red>// block size caveat exists of course.</font> - ACE_Message_Block * decrypted = new ACE_Message_Block( message->size() ); - - <font color=red>// Check the signature as expected.</font> - if( <font color=#008888>ACE_OS::strncmp</font>( message->rd_ptr(), "<font color=green>ED:</font>", 3 ) ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Improperly encrypted data.\n</font>" )); - message->release(); - return(-1); - } - - <font color=red>// Don't forget to skip past the signature before decrypting</font> - <font color=red>// or things will be quite exciting!</font> - message->rd_ptr( 3 ); - - <font color=red>// Perform a bogus decryption algorithm</font> - <font color=#008888>ACE_OS::sprintf</font>( decrypted->wr_ptr(), "<font color=green>%s</font>", message->rd_ptr() ); - decrypted->wr_ptr( strlen(decrypted->wr_ptr())+1 ); - - <font color=red>// Send the decrypted data down the stream to the next module</font> - this->put_next( decrypted ); - - <font color=red>// We're done here.</font> - message->release(); - - return( 0 ); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page22.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/015/page22.html b/docs/tutorials/015/page22.html deleted file mode 100644 index 2c412e41b30..00000000000 --- a/docs/tutorials/015/page22.html +++ /dev/null @@ -1,82 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 015</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 015</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Building a protocol stream</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Well, this has certainly been one of the more verbose tutorials to -date. I must say "thanks" to everyone who stuck it out this far! -<P> -A quick review of what we've done: -<UL> - -<LI>Create a simple client application and Client object that uses a -Protocol Stream without really knowing how they work. The app (and -object) rely on the public interface of the Protocol Stream to get the -job done. At this level the protocol details are irrelevant. -<P> -<LI>Next, we create a simple server application and Server object -similar to the client. The Protocol Stream is of course used and we -have to know a little more so that we can insert a <i>reader</i> that -will ultimately process the data from the client. -<P> -<LI>We then go into the details of the Protocol_Stream implementation -and it's Protocol_Task object that forms the basis for the stream -tasks. Each object is kept as small and simple as possible to improve -reusability and future maintenance. -<P> -<LI>Finally, the individual protocol objects are discused. Separate -objects for the peer interface were created as well as the bogus -compressor and encryptor. The protocol can be extended or modified by -creating new such objects and installing them in the Protocol_Stream's -open() method. - -</UL> -<P> - -It doesn't sound like much but it certainly took a bunch of files to -get there. It's easy to get lost in the details when there's so much -to cover so you're encouraged to go over things a couple of times. -As always, enhancments of the tutorials is welcome! -<P> -Here's the complete file list: -<UL> -<LI><A HREF="client">Makefile</A> -<P> -<LI><A HREF="Makefile.client">client Makefile</A> -<LI><A HREF="client.cpp">client.cpp</A> -<LI><A HREF="Client_i.h">Client_i.h</A> -<LI><A HREF="Client_i.cpp">Client_i.cpp</A> -<P> -<LI><A HREF="Makefile.server">Server Makefile</A> -<LI><A HREF="server.cpp">server.cpp</A> -<LI><A HREF="Server_i.h">Server_i.h</A> -<LI><A HREF="Server_i.cpp">Server_i.cpp</A> -<LI><A HREF="Handler.h">Handler.h</A> -<LI><A HREF="Handler.cpp">Handler.cpp</A> -<P> -<LI><A HREF="Protocol_Stream.cpp">Protocol_Stream.cpp</A> -<LI><A HREF="Protocol_Stream.h">Protocol_Stream.h</A> -<LI><A HREF="Protocol_Task.cpp">Protocol_Task.cpp</A> -<LI><A HREF="Protocol_Task.h">Protocol_Task.h</A> -<P> -<LI><A HREF="Xmit.cpp">Xmit.cpp</A> -<LI><A HREF="Xmit.h">Xmit.h</A> -<LI><A HREF="Recv.cpp">Recv.cpp</A> -<LI><A HREF="Recv.h">Recv.h</A> -<P> -<LI><A HREF="Compressor.cpp">Compressor.cpp</A> -<LI><A HREF="Compressor.h">Compressor.h</A> -<LI><A HREF="Crypt.cpp">Crypt.cpp</A> -<LI><A HREF="Crypt.h">Crypt.h</A> -</UL> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/015/server.cpp b/docs/tutorials/015/server.cpp deleted file mode 100644 index bface44e341..00000000000 --- a/docs/tutorials/015/server.cpp +++ /dev/null @@ -1,46 +0,0 @@ - -// $Id$ - -#include "Server_i.h" - -// A signal handler that will close the server object -extern "C" void handler (int) -{ - Server::close(); -} - -int main (int, char **) -{ - // The server object that abstracts away all of difficult parts. - Server server; - - // Attempt to open the server. Like all good ACE-based - // objects, we'll get -1 on failure. - if( server.open() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "server.open()"), -1); - } - - // Install a signal handler for ^C so that we can exit gracefully - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT); - - // Run the server's main loop until we're interrupted - if( server.run() == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "server.run()"), -1); - } - - return 0; -} - -/* These explicit instantiations were taken from an earlier tutorial. - Your compiler may require others as well. -*/ -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - diff --git a/docs/tutorials/015/stream.gif b/docs/tutorials/015/stream.gif Binary files differdeleted file mode 100644 index daae2420b74..00000000000 --- a/docs/tutorials/015/stream.gif +++ /dev/null diff --git a/docs/tutorials/016/016.dsp b/docs/tutorials/016/016.dsp deleted file mode 100644 index 3adcf4cc9db..00000000000 --- a/docs/tutorials/016/016.dsp +++ /dev/null @@ -1,108 +0,0 @@ -# Microsoft Developer Studio Project File - Name="016" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=016 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "016.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "016.mak" CFG="016 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "016 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "016 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "016 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "016 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"condition.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "016 - Win32 Release"
-# Name "016 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\condition.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Condition_i.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\Condition_i.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/016/Condition_i.cpp b/docs/tutorials/016/Condition_i.cpp deleted file mode 100644 index d7facf62c80..00000000000 --- a/docs/tutorials/016/Condition_i.cpp +++ /dev/null @@ -1,201 +0,0 @@ - -// $Id$ - -// Get or declaration -#include "Condition_i.h" - -/* Initialize the condition variable and create the condition mutex. - Since I don't have any guarantees on the order of member variable - initialization, I have to new the condition mutex instead of - simply constructing it. - */ -Condition::Condition(value_t _value) - : value_(_value) -{ - condition_ = new condition_t( this->mutex() ); -} - -Condition::~Condition(void) -{ - // Be sure we don't have a memeory leak - delete condition_; -} - -/* The cast operator is the easiest way to return a copy of the value - to clients of the class. It also allows us to use a private method - for getting a reference to the value when we need to modify it. - */ -Condition::operator Condition::value_t (void) -{ - // Place a guard around the variable so that it won't change as - // we're copying it back to the client. - guard_t guard(mutex_); - return value(); -} - -/* Traditional prefix increment operator. - We place a guard around the operation so that we don't collide with - any other threads. After the modification, we broadcast() a - condition change to any waiting threads. You can also use signal() - but that will only tell one thread about the change. If that - thread, in turn, invokes signal() then all threads will eventually - find out. I just thought it would be easier to use broadcast() and - be done with it. - */ -Condition & Condition::operator++ (void) -{ - guard_t guard(mutex_); - - ++value(); - - condition().broadcast(); - - return *this; -} - -/* The remaining operators all follow the same pattern that we have - above. They only differ in the modification they make to the value(). - */ - -Condition & Condition::operator-- (void) -{ - guard_t guard(mutex_); - - --value(); - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator+= (int _inc) -{ - guard_t guard(mutex_); - - value() += _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator-= (int _inc) -{ - guard_t guard(mutex_); - - value() -= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator*= (int _inc) -{ - guard_t guard(mutex_); - - value() *= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator/= (int _inc) -{ - guard_t guard(mutex_); - - value() /= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator%= (int _inc) -{ - guard_t guard(mutex_); - - value() %= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator= ( value_t _value ) -{ - guard_t guard(mutex_); - - value() = _value; - - condition().broadcast(); - - return *this; -} - -/* Now we get into the comparison area. - Each one follows the pattern we've already established for - waiters. - */ - -/* - We begin with an equality operator that expects a function object. - In the while() test we pass a copy of the value to the function - object for evaluation. The object can then do any comparision it - wants to check for a desired condition. When the function object - returns non-zero, the condition is met and we leave. - */ -int Condition::operator== ( Condition::Compare & _compare ) -{ - guard_t guard(mutex_); - - while( ! _compare(this->value()) ) - condition().wait(); - - return 0; -} - -// As long as the variable equals _value, we wait... -int Condition::operator== ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() == _value ) - condition().wait(); - - return 0; -} - -// As long as the variable is not equal to _value, we wait... -int Condition::operator!= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() != _value ) - condition().wait(); - - return 0; -} - -// As long as the variable is less than or equal to _value, we wait... -int Condition::operator<= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() <= _value ) - condition().wait(); - - return 0; -} - -// As long as the variable is greater than or equal to _value, we wait... -int Condition::operator>= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() >= _value ) - condition().wait(); - - return 0; -} diff --git a/docs/tutorials/016/Condition_i.h b/docs/tutorials/016/Condition_i.h deleted file mode 100644 index 1bbc704af6f..00000000000 --- a/docs/tutorials/016/Condition_i.h +++ /dev/null @@ -1,159 +0,0 @@ - -// $Id$ - -#ifndef CONDITION_H -#define CONDITION_H - -#include "ace/Synch.h" - -/** A wrapper for ACE_Condition<>. - When you're using an ACE_Condition<> you have to have three things: - - Some variable that embodies the condition you're looking for - - A mutex to prevent simultaneous access to that variable from different threads - - An ACE_Condition<> that enables blocking on state changes in the variable - The class I create here will contain those three things. For the - actual condition variable I've chosen an integer. You could - easily turn this clas into a template parameterized on the - condition variable's data type if 'int' isn't what you want. - */ -class Condition -{ -public: - // From here on I'll use value_t instead of 'int' to make any - // future upgrades easier. - typedef int value_t; - - // Initialize the condition variable - Condition(value_t _value = 0); - ~Condition(void); - - /* I've created a number of arithmetic operators on the class - that pass their operation on to the variable. If you turn - this into a template then some of these may not be - appropriate... - For the ones that take a parameter, I've stuck with 'int' - instead of 'value_t' to reinforce the fact that you'll need - a close look at these if you choose to change the 'value_t' - typedef. - */ - - // Increment & decrement - Condition & operator++(void); - Condition & operator--(void); - - // Increase & decrease - Condition & operator+=(int _inc); - Condition & operator-=(int _inc); - - // Just to be complete - Condition & operator*=(int _inc); - Condition & operator/=(int _inc); - Condition & operator%=(int _inc); - - // Set/Reset the condition variable's value - Condition & operator=( value_t _value ); - - /* These four operators perform the actual waiting. For - instance: - - operator!=(int _value) - - is implemented as: - - Guard guard(mutex_) - while( value_ != _value ) - condition_.wait(); - - This is the "typical" use for condition mutexes. Each of - the operators below behaves this way for their respective - comparisions. - - To use one of these in code, you would simply do: - - Condition mycondition; - ... - // Wait until the condition variable has the value 42 - mycondition != 42 - ... - */ - - // As long as the condition variable is NOT EQUAL TO _value, we wait - int operator!=( value_t _value ); - // As long as the condition variable is EXACTLY EQUAL TO _value, we wait - int operator==( value_t _value ); - // As long as the condition variable is LESS THAN OR EQUAL TO _value, we wait - int operator<=( value_t _value ); - // As long as the condition variable is GREATER THAN OR EQUAL TO _value, we wait - int operator>=( value_t _value ); - - // Return the value of the condition variable - operator value_t (void); - - /* In addition to the four ways of waiting above, I've also - create a method that will invoke a function object for each - iteration of the while() loop. - Derive yourself an object from Condition::Compare and - overload operator()(value_t) to take advantage of this. Have - the function return non-zero when you consider the condition - to be met. - */ - class Compare - { - public: - virtual int operator() ( value_t _value ) = 0; - }; - - /* Wait on the condition until _compare(value) returns - non-zero. This is a little odd since we're not really testing - equality. Just be sure that _compare(value_) will return - non-zero when you consider the condition to be met. - */ - int operator==( Compare & _compare ); - -private: - // Prevent copy construction and assignment. - Condition( const Condition & _condition ); - Condition & operator= ( const Condition & _condition ); - - /* Typedefs make things easier to change later. - ACE_Condition_Thread_Mutex is used as a shorthand for - ACE_Condition<ACE_Thread_Mutex> and also because it may - provide optimizations we can use. - */ - typedef ACE_Thread_Mutex mutex_t; - typedef ACE_Condition_Thread_Mutex condition_t; - typedef ACE_Guard<mutex_t> guard_t; - - // The mutex that keeps the data save - mutex_t mutex_; - - // The condition mutex that makes waiting on the condition - // easier. - condition_t * condition_; - - // The acutal variable that embodies the condition we're - // waiting for. - value_t value_; - - // Accessors for the two mutexes. - mutex_t & mutex(void) - { - return this->mutex_; - } - - condition_t & condition(void) - { - return *(this->condition_); - } - - // This particular accessor will make things much easier if we - // decide that 'int' isn't the correct datatype for value_. - // Note that we keep this private and force clients of the class - // to use the cast operator to get a copy of the value. - value_t & value(void) - { - return this->value_; - } -}; - -#endif // CONDITION_H diff --git a/docs/tutorials/016/Makefile b/docs/tutorials/016/Makefile deleted file mode 100644 index 65ce0bb1352..00000000000 --- a/docs/tutorials/016/Makefile +++ /dev/null @@ -1,74 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = condition - -FILES = Condition_i - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre > combine.shar && rm -f hdr bodies *.pre - -UNSHAR : # - sh combine.shar - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/016/combine.shar b/docs/tutorials/016/combine.shar deleted file mode 100644 index 503f70b83be..00000000000 --- a/docs/tutorials/016/combine.shar +++ /dev/null @@ -1,332 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-10-29 15:09 EST by <jcej@caldera.lads.com>. -# Source directory was `/scsiA/home/jcej/projects/ACE_wrappers/docs/tutorials/016'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 422 -rw-rw-r-- hdr -# 50 -rw-rw-r-- bodies -# 789 -rw-rw-r-- page01.pre -# 1350 -rw-rw-r-- page02.pre -# 248 -rw-rw-r-- page03.pre -# 309 -rw-rw-r-- page04.pre -# 605 -rw-rw-r-- page05.pre -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh03957; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1029153498 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -34600093c989939b7a2a6806f2b18f22 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 422 -eq "$shar_count" || - $echo 'hdr:' 'original size' '422,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -Condition_i.h -Condition_i.cpp -condition.cpp -SHAR_EOF - $shar_touch -am 1029153398 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -06c11389b22b88d88110d2338c4dbaaf bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 50 -eq "$shar_count" || - $echo 'bodies:' 'original size' '50,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -The ACE framework has quite a few objects for syncronizing your -threads and even processes. We've mentioned a few in passing already: -X ACE_Thread_Mutex and ACE_Barrier for instance. -<P> -Another interesting one is the ACE_Condition template. By using an -ACE_Condition you can have your code wait for an arbitrary condition -to occur. That condition is "embodied" in a variable of your choice. -That variable can, in turn, be any data type you wish. This makes -ACE_Condition much more flexible than a simple mutex, barrier or -semaphore. -<P> -In this tutorial, I'll create a wrapper class around the ACE_Condition -and the assorted housekeeping items necessary to make it work. I'll -use a simple integer as the condition variable but keep in mind that -you can use any data type you want. -SHAR_EOF - $shar_touch -am 1029153198 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -aa9f5774f5415d7a430891e9296bfab0 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 789 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '789,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -We'll look first at the declaration of the wrapper class. -<P> -The way you use ACE_Condition is something like this: -<UL> -<LI>First, the setup... -<UL> -<LI>Create a variable using your choice of data types -<LI>Create a mutex that will provide thread-safe access to that -variable -<LI>Create an ACE_Condition that uses the mutex -</UL> -<P> -<LI>Waiting for the condition... -<UL> -<PRE> -the_mutex.acquire(); -while( the_variable != some_desired_state_or_value ) -X the_condition.wait(); -the_mutex.release(); -</PRE> -Note that when <i>the_condition</i> is created, it must be given a -reference to the mutex. That's because the wait() method will release -the mutex before waiting and reacquire it after being signaled. -</UL> -<P> -<LI>Setting the condition... -<UL> -<PRE> -the_mutex.acquire(); -the_variable = some_new_value_or_state; -the_condition.signal() <i>OR</i> the_condition.broadcast() -</pre> -</UL> -</UL> -<P> -The problem I have is remembering to setup everything and co-ordinate -the locking, waiting and signaling. Even if I remember it all -correctly it just makes my application code more complex than it -should be. -<P> -To help out with that, I've created the class below to encapsulate the -three elements necessary for the condition to work. I've then added -methods for manipulation of the condition variable and waiting for the -condition to occur. -<HR> -SHAR_EOF - $shar_touch -am 1029191498 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -ccf4d7623038838df6249b5134827402 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 1350 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '1350,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -Ok, now we'll take a look at the definition of the class. You already -know how to use an ACE_Condition & it's not really that difficult. -Still, imagine how much more cluttered your code would be if it had to -include the mess I've got below! -<HR> -SHAR_EOF - $shar_touch -am 1029162998 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -51c4ebc7f5c67e072fed8f76bd7be62d page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 248 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '248,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -We finally get to the main() application. I create a simple Task -derivative that will serve as a baseclass for other objects that test -specific functions of the Condition class. Notice how easy it is to -integrate a Condition into the application without keeping track of -three related member variables. -<HR> -SHAR_EOF - $shar_touch -am 1029185698 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -b6694ddc18814a64feeb56f46ffd7d17 page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 309 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '309,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -And that's all... -<P> -For general use, it would make sense to convert Condition into a -template and get rid of some of the operators that don't make sense. -Using an integer as the condition type probably isn't realistic since -you could just use a semaphore or barrier for that case. Still, the -Tutorial shows the basics and provides a foundation on which you can -create a more useful class for your application. -<P> -<UL> -<LI><A HREF="Condition_i.h">Condition_i.h</A> -<LI><A HREF="Condition_i.cpp">Condition_i.cpp</A> -<LI><A HREF="condition.cpp">condition.cpp</A> -<LI><A HREF="Makefile">Makefile</A> -</UL> -SHAR_EOF - $shar_touch -am 1029192198 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -f63c4bfe37b1fe5785a6af9b204cb0bf page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 605 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '605,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh03957 -exit 0 diff --git a/docs/tutorials/016/condition.cpp b/docs/tutorials/016/condition.cpp deleted file mode 100644 index 5ec772a4a7f..00000000000 --- a/docs/tutorials/016/condition.cpp +++ /dev/null @@ -1,249 +0,0 @@ - -// $Id$ - -#include "Condition_i.h" -#include "ace/Task.h" - -/* In order to test our Condition we'll derive from ACE_Task<> so that - we can have several threads accessing the condition variable - together. - */ -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - // Construct the condition variable with an initial value. - Test( Condition::value_t _value ); - ~Test(void); - - // Open the Task with enough threads to make a useful test. - int open(void); - -protected: - // Each thread will do work on the Condition. - int svc(void); - - // Override this method to modify the Condition in some way. - virtual void modify(void) = 0; - // Override this to test the Condition in some way. - virtual void test(void) = 0; - - // How many threads to use in the test. This is also used in the - // modify() and test() methods of the derivatives. - static const int max_threads_; - - // We want to sleep for a random amount of time to simulate - // work. The seed is necessary for proper random number generation. - ACE_RANDR_TYPE seed_; - - // This is the actual condition variable set. - Condition condition_; -}; - -// Set the number of threads. -const int Test::max_threads_ = 5; - -// Initialize the condition variable. -Test::Test( Condition::value_t _value ) - : condition_(_value) -{ - ; -} - -Test::~Test(void) -{ - ; -} - -// Seed the random number generator and start the threads. -int Test::open(void) -{ - seed_ = ACE_OS::gettimeofday().usec(); - - ACE_OS::srand( seed_ ); - - return this->activate(THR_NEW_LWP, max_threads_); -} - -/* Each thread will modify the condition variable in some way and then - wait for the condition to be satisfied. The derived classes - overload modify() and test() to implement a specific test of the - Condition class. - */ -int Test::svc(void) -{ - // Take a moment before we modify the condition. This will - // cause test() in other threads to delay a bit. - int stime = ACE_OS::rand_r( seed_ ) % 5; - ACE_OS::sleep(abs(stime)+2); - - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() befor modify, condition_ is: %d\n", (int)condition_ )); - - // Change the condition variable's value - modify(); - - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() after modify, condition_ is: %d\n", (int)condition_ )); - - // Test for the condition we want - test(); - - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() leaving.\n" )); - - return(0); -} - -/* Test Condition::operator!=() - The task's svc() method will increment the condition variable and - then wait until the variable's value reaches max_threads_. - */ -class Test_ne : public Test -{ -public: - // Initialize the condition variable to zero since we're counting up. - Test_ne(void) - : Test(0) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ != %d\n", max_threads_)); - } - - // Increment the variable - void modify(void) - { - ++condition_; - } - - // Wait until it equals max_threads_ - void test(void) - { - condition_ != max_threads_; - } -}; - -/* Test Condition::operator>=() - Each svc() method will decrement the condition variable and wait - until it is less than max_threads_. To do this correctly, we have - to be careful where we start the condition variable. - */ -class Test_ge : public Test -{ -public: - // For max_threads_ == 5, we will start the condition variable at - // the value 9. When the "last" thread decrements it, the value - // will be 4 which satisfies the condition. - Test_ge(void) - : Test(max_threads_*2-1) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ >= %d\n", max_threads_)); - } - - // Decrement by one... - void modify(void) - { - --condition_; - } - - // while( value >= max_threads_ ) wait(); - void test(void) - { - condition_ >= max_threads_; - } -}; - -/* Test Condition::operator<=() - This time we will increment the condition until it is greater than - max_threads_. Again, we have to be careful where we start the - value and how we increment. - */ -class Test_le : public Test -{ -public: - // I'm starting the value at 1 so that if we increment by one in - // each thread, the "last" thread (of 5) will set the value to - // 6. Since I actually increment by 2, we could start somewhat lower. - Test_le(void) - : Test(1) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ <= %d\n", max_threads_)); - } - - // Try out Condition::operator+=(int) - // This will cause the third thread to satisfy the condition. - void modify(void) - { - condition_ += 2; - } - - // while( value <= max_threads_ ) wait(); - void test(void) - { - condition_ <= max_threads_; - } -}; - -/* For our final test, we'll go after Condition::operator=(Condition::Compare) - By deriving from Condition::Compare we can perform any arbitrary - test on the value of the condition variable. - */ -class Test_fo : public Test -{ -public: - // We'll be using operator*=(int) to increment the condition - // variable, so we need to start with a non-zero value. - Test_fo(void) - : Test(1) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ == FunctionObject\n" )); - } - - // Double the value for each thread that we have. - void modify(void) - { - condition_ *= 2; - } - - /* Derive our CompareFunction and provide the operator() that - performs our test. In this case, we'll compare the value to - the number 32. - */ - class CompareFunction : public Condition::Compare - { - public: - // When this returns non-zero, the condition test operator - // will unblock in each thread. - int operator() ( Condition::value_t _value ) - { - return _value == 32; - } - }; - - // Create the CompareFunction and wait for the condition variable - // to reach the state we want. - void test(void) - { - CompareFunction compare; - condition_ == compare; - } -}; - -/* In main() we just instantiate each of the four test objects that we - created. After open()ing each, we wait() for it's threads to exit. - */ -int main(int, char **) -{ - Test_ne test_ne; - test_ne.open(); - test_ne.wait(); - - Test_ge test_ge; - test_ge.open(); - test_ge.wait(); - - Test_le test_le; - test_le.open(); - test_le.wait(); - - Test_fo test_fo; - test_fo.open(); - test_fo.wait(); - - return(0); -} diff --git a/docs/tutorials/016/page01.html b/docs/tutorials/016/page01.html deleted file mode 100644 index 057ca7142d9..00000000000 --- a/docs/tutorials/016/page01.html +++ /dev/null @@ -1,31 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The ACE framework has quite a few objects for syncronizing your -threads and even processes. We've mentioned a few in passing already: - ACE_Thread_Mutex and ACE_Barrier for instance. -<P> -Another interesting one is the ACE_Condition template. By using an -ACE_Condition you can have your code wait for an arbitrary condition -to occur. That condition is "embodied" in a variable of your choice. -That variable can, in turn, be any data type you wish. This makes -ACE_Condition much more flexible than a simple mutex, barrier or -semaphore. -<P> -In this tutorial, I'll create a wrapper class around the ACE_Condition -and the assorted housekeeping items necessary to make it work. I'll -use a simple integer as the condition variable but keep in mind that -you can use any data type you want. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/016/page02.html b/docs/tutorials/016/page02.html deleted file mode 100644 index fdcfc4e8c1b..00000000000 --- a/docs/tutorials/016/page02.html +++ /dev/null @@ -1,221 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -We'll look first at the declaration of the wrapper class. -<P> -The way you use ACE_Condition is something like this: -<UL> -<LI>First, the setup... -<UL> -<LI>Create a variable using your choice of data types -<LI>Create a mutex that will provide thread-safe access to that -variable -<LI>Create an ACE_Condition that uses the mutex -</UL> -<P> -<LI>Waiting for the condition... -<UL> -<PRE> -the_mutex.acquire(); -while( the_variable != some_desired_state_or_value ) - the_condition.wait(); -the_mutex.release(); -</PRE> -Note that when <i>the_condition</i> is created, it must be given a -reference to the mutex. That's because the wait() method will release -the mutex before waiting and reacquire it after being signaled. -</UL> -<P> -<LI>Setting the condition... -<UL> -<PRE> -the_mutex.acquire(); -the_variable = some_new_value_or_state; -the_condition.signal() <i>OR</i> the_condition.broadcast() -</pre> -</UL> -</UL> -<P> -The problem I have is remembering to setup everything and co-ordinate -the locking, waiting and signaling. Even if I remember it all -correctly it just makes my application code more complex than it -should be. -<P> -To help out with that, I've created the class below to encapsulate the -three elements necessary for the condition to work. I've then added -methods for manipulation of the condition variable and waiting for the -condition to occur. -<HR><PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>CONDITION_H</font> -<font color=blue>#define</font> <font color=purple>CONDITION_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Synch.h</font>" - -<font color=red>/** A wrapper for ACE_Condition<>. - When you're using an ACE_Condition<> you have to have three things: - - Some variable that embodies the condition you're looking for - - A mutex to prevent simultaneous access to that variable from different threads - - An ACE_Condition<> that enables blocking on state changes in the variable - The class I create here will contain those three things. For the - actual condition variable I've chosen an integer. You could - easily turn this clas into a template parameterized on the - condition variable's data type if 'int' isn't what you want. - */</font> -class Condition -{ -public: - <font color=red>// From here on I'll use value_t instead of 'int' to make any</font> - <font color=red>// future upgrades easier.</font> - typedef int value_t; - - <font color=red>// Initialize the condition variable</font> - Condition(value_t _value = 0); - ~Condition(void); - - <font color=red>/* I've created a number of arithmetic operators on the class - that pass their operation on to the variable. If you turn - this into a template then some of these may not be - appropriate... - For the ones that take a parameter, I've stuck with 'int' - instead of 'value_t' to reinforce the fact that you'll need - a close look at these if you choose to change the 'value_t' - typedef. - */</font> - - <font color=red>// Increment & decrement</font> - Condition & operator++(void); - Condition & operator--(void); - - <font color=red>// Increase & decrease</font> - Condition & operator+=(int _inc); - Condition & operator-=(int _inc); - - <font color=red>// Just to be complete</font> - Condition & operator*=(int _inc); - Condition & operator/=(int _inc); - Condition & operator%=(int _inc); - - <font color=red>// Set/Reset the condition variable's value</font> - Condition & operator=( value_t _value ); - - <font color=red>/* These four operators perform the actual waiting. For - instance: - - operator!=(int _value) - - is implemented as: - - Guard guard(mutex_) - while( value_ != _value ) - condition_.wait(); - - This is the "<font color=green>typical</font>" use for condition mutexes. Each of - the operators below behaves this way for their respective - comparisions. - - To use one of these in code, you would simply do: - - Condition mycondition; - ... - <font color=red>// Wait until the condition variable has the value 42</font> - mycondition != 42 - ... - */</font> - - <font color=red>// As long as the condition variable is NOT EQUAL TO _value, we wait</font> - int operator!=( value_t _value ); - <font color=red>// As long as the condition variable is EXACTLY EQUAL TO _value, we wait</font> - int operator==( value_t _value ); - <font color=red>// As long as the condition variable is LESS THAN OR EQUAL TO _value, we wait</font> - int operator<=( value_t _value ); - <font color=red>// As long as the condition variable is GREATER THAN OR EQUAL TO _value, we wait</font> - int operator>=( value_t _value ); - - <font color=red>// Return the value of the condition variable</font> - operator value_t (void); - - <font color=red>/* In addition to the four ways of waiting above, I've also - create a method that will invoke a function object for each - iteration of the while() loop. - Derive yourself an object from <font color=#008888>Condition::Compare</font> and - overload operator()(value_t) to take advantage of this. Have - the function return non-zero when you consider the condition - to be met. - */</font> - class Compare - { - public: - virtual int operator() ( value_t _value ) = 0; - }; - - <font color=red>/* Wait on the condition until _compare(value) returns - non-zero. This is a little odd since we're not really testing - equality. Just be sure that _compare(value_) will return - non-zero when you consider the condition to be met. - */</font> - int operator==( Compare & _compare ); - -private: - <font color=red>// Prevent copy construction and assignment.</font> - Condition( const Condition & _condition ); - Condition & operator= ( const Condition & _condition ); - - <font color=red>/* Typedefs make things easier to change later. - ACE_Condition_Thread_Mutex is used as a shorthand for - ACE_Condition<ACE_Thread_Mutex> and also because it may - provide optimizations we can use. - */</font> - typedef ACE_Thread_Mutex mutex_t; - typedef ACE_Condition_Thread_Mutex condition_t; - typedef ACE_Guard<mutex_t> guard_t; - - <font color=red>// The mutex that keeps the data save</font> - mutex_t mutex_; - - <font color=red>// The condition mutex that makes waiting on the condition</font> - <font color=red>// easier.</font> - condition_t * condition_; - - <font color=red>// The acutal variable that embodies the condition we're</font> - <font color=red>// waiting for.</font> - value_t value_; - - <font color=red>// Accessors for the two mutexes.</font> - mutex_t & mutex(void) - { - return this->mutex_; - } - - condition_t & condition(void) - { - return *(this->condition_); - } - - <font color=red>// This particular accessor will make things much easier if we </font> - <font color=red>// decide that 'int' isn't the correct datatype for value_.</font> - <font color=red>// Note that we keep this private and force clients of the class</font> - <font color=red>// to use the cast operator to get a copy of the value.</font> - value_t & value(void) - { - return this->value_; - } -}; - -<font color=blue>#endif</font> <font color=red>// CONDITION_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/016/page03.html b/docs/tutorials/016/page03.html deleted file mode 100644 index 43e65f5001b..00000000000 --- a/docs/tutorials/016/page03.html +++ /dev/null @@ -1,224 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Ok, now we'll take a look at the definition of the class. You already -know how to use an ACE_Condition & it's not really that difficult. -Still, imagine how much more cluttered your code would be if it had to -include the mess I've got below! -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// Get or declaration</font> -<font color=blue>#include</font> "<font color=green>Condition_i.h</font>" - -<font color=red>/* Initialize the condition variable and create the condition mutex. - Since I don't have any guarantees on the order of member variable - initialization, I have to new the condition mutex instead of - simply constructing it. - */</font> -<font color=#008888>Condition::Condition</font>(value_t _value) - : value_(_value) -{ - condition_ = new condition_t( this->mutex() ); -} - -<font color=#008888>Condition::~Condition</font>(void) -{ - <font color=red>// Be sure we don't have a memeory leak</font> - delete condition_; -} - -<font color=red>/* The cast operator is the easiest way to return a copy of the value - to clients of the class. It also allows us to use a private method - for getting a reference to the value when we need to modify it. - */</font> -<font color=#008888>Condition::operator</font> value_t (void) -{ - <font color=red>// Place a guard around the variable so that it won't change as</font> - <font color=red>// we're copying it back to the client.</font> - guard_t guard(mutex_); - return value(); -} - -<font color=red>/* Traditional prefix increment operator. - We place a guard around the operation so that we don't collide with - any other threads. After the modification, we broadcast() a - condition change to any waiting threads. You can also use signal() - but that will only tell one thread about the change. If that - thread, in turn, invokes signal() then all threads will eventually - find out. I just thought it would be easier to use broadcast() and - be done with it. - */</font> -Condition & <font color=#008888>Condition::operator</font>++ (void) -{ - guard_t guard(mutex_); - - ++value(); - - condition().broadcast(); - - return *this; -} - -<font color=red>/* The remaining operators all follow the same pattern that we have - above. They only differ in the modification they make to the value(). - */</font> - -Condition & <font color=#008888>Condition::operator</font>-- (void) -{ - guard_t guard(mutex_); - - --value(); - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>+= (int _inc) -{ - guard_t guard(mutex_); - - value() += _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>-= (int _inc) -{ - guard_t guard(mutex_); - - value() -= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>*= (int _inc) -{ - guard_t guard(mutex_); - - value() *= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>/= (int _inc) -{ - guard_t guard(mutex_); - - value() /= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>%= (int _inc) -{ - guard_t guard(mutex_); - - value() %= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>= ( value_t _value ) -{ - guard_t guard(mutex_); - - value() = _value; - - condition().broadcast(); - - return *this; -} - -<font color=red>/* Now we get into the comparison area. - Each one follows the pattern we've already established for - waiters. - */</font> - -<font color=red>/* - We begin with an equality operator that expects a function object. - In the while() test we pass a copy of the value to the function - object for evaluation. The object can then do any comparision it - wants to check for a desired condition. When the function object - returns non-zero, the condition is met and we leave. - */</font> -int <font color=#008888>Condition::operator</font>== ( Condition::Compare & _compare ) -{ - guard_t guard(mutex_); - - while( ! _compare(this->value()) ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable equals _value, we wait...</font> -int <font color=#008888>Condition::operator</font>== ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() == _value ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable is not equal to _value, we wait...</font> -int <font color=#008888>Condition::operator</font>!= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() != _value ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable is less than or equal to _value, we wait...</font> -int <font color=#008888>Condition::operator</font><= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() <= _value ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable is greater than or equal to _value, we wait...</font> -int <font color=#008888>Condition::operator</font>>= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() >= _value ) - condition().wait(); - - return 0; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/016/page04.html b/docs/tutorials/016/page04.html deleted file mode 100644 index 75c953961cc..00000000000 --- a/docs/tutorials/016/page04.html +++ /dev/null @@ -1,272 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -We finally get to the main() application. I create a simple Task -derivative that will serve as a baseclass for other objects that test -specific functions of the Condition class. Notice how easy it is to -integrate a Condition into the application without keeping track of -three related member variables. -<HR><PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Condition_i.h</font>" -<font color=blue>#include</font> "<font color=green>ace/Task.h</font>" - -<font color=red>/* In order to test our Condition we'll derive from ACE_Task<> so that - we can have several threads accessing the condition variable - together. - */</font> -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - <font color=red>// Construct the condition variable with an initial value.</font> - Test( <font color=#008888>Condition::value_t</font> _value ); - ~Test(void); - - <font color=red>// Open the Task with enough threads to make a useful test.</font> - int open(void); - -protected: - <font color=red>// Each thread will do work on the Condition.</font> - int svc(void); - - <font color=red>// Override this method to modify the Condition in some way.</font> - virtual void modify(void) = 0; - <font color=red>// Override this to test the Condition in some way.</font> - virtual void test(void) = 0; - - <font color=red>// How many threads to use in the test. This is also used in the</font> - <font color=red>// modify() and test() methods of the derivatives.</font> - static const int max_threads_; - - <font color=red>// We want to sleep for a random amount of time to simulate</font> - <font color=red>// work. The seed is necessary for proper random number generation.</font> - ACE_RANDR_TYPE seed_; - - <font color=red>// This is the actual condition variable set.</font> - Condition condition_; -}; - -<font color=red>// Set the number of threads.</font> -const int <font color=#008888>Test::max_threads_</font> = 5; - -<font color=red>// Initialize the condition variable.</font> -<font color=#008888>Test::Test</font>( Condition::value_t _value ) - : condition_(_value) -{ - ; -} - -<font color=#008888>Test::~Test</font>(void) -{ - ; -} - -<font color=red>// Seed the random number generator and start the threads.</font> -int <font color=#008888>Test::open</font>(void) -{ - seed_ = <font color=#008888>ACE_OS::gettimeofday</font>().usec(); - - <font color=#008888>ACE_OS::srand</font>( seed_ ); - - return this->activate(THR_NEW_LWP, max_threads_); -} - -<font color=red>/* Each thread will modify the condition variable in some way and then - wait for the condition to be satisfied. The derived classes - overload modify() and test() to implement a specific test of the - Condition class. - */</font> -int <font color=#008888>Test::svc</font>(void) -{ - <font color=red>// Take a moment before we modify the condition. This will</font> - <font color=red>// cause test() in other threads to delay a bit.</font> - int stime = <font color=#008888>ACE_OS::rand_r</font>( seed_ ) % 5; - <font color=#008888>ACE_OS::sleep</font>(abs(stime)+2); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() befor modify, condition_ is: %d\n</font>", (int)condition_ )); - - <font color=red>// Change the condition variable's value</font> - modify(); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() after modify, condition_ is: %d\n</font>", (int)condition_ )); - - <font color=red>// Test for the condition we want</font> - test(); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() leaving.\n</font>" )); - - return(0); -} - -<font color=red>/* Test <font color=#008888>Condition::operator</font>!=() - The task's svc() method will increment the condition variable and - then wait until the variable's value reaches max_threads_. - */</font> -class Test_ne : public Test -{ -public: - <font color=red>// Initialize the condition variable to zero since we're counting up.</font> - Test_ne(void) - : Test(0) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ != %d\n</font>", max_threads_)); - } - - <font color=red>// Increment the variable</font> - void modify(void) - { - ++condition_; - } - - <font color=red>// Wait until it equals max_threads_</font> - void test(void) - { - condition_ != max_threads_; - } -}; - -<font color=red>/* Test <font color=#008888>Condition::operator</font>>=() - Each svc() method will decrement the condition variable and wait - until it is less than max_threads_. To do this correctly, we have - to be careful where we start the condition variable. - */</font> -class Test_ge : public Test -{ -public: - <font color=red>// For max_threads_ == 5, we will start the condition variable at </font> - <font color=red>// the value 9. When the "<font color=green>last</font>" thread decrements it, the value</font> - <font color=red>// will be 4 which satisfies the condition.</font> - Test_ge(void) - : Test(max_threads_*2-1) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ >= %d\n</font>", max_threads_)); - } - - <font color=red>// Decrement by one...</font> - void modify(void) - { - --condition_; - } - - <font color=red>// while( value >= max_threads_ ) wait();</font> - void test(void) - { - condition_ >= max_threads_; - } -}; - -<font color=red>/* Test <font color=#008888>Condition::operator</font><=() - This time we will increment the condition until it is greater than - max_threads_. Again, we have to be careful where we start the - value and how we increment. - */</font> -class Test_le : public Test -{ -public: - <font color=red>// I'm starting the value at 1 so that if we increment by one in</font> - <font color=red>// each thread, the "<font color=green>last</font>" thread (of 5) will set the value to</font> - <font color=red>// 6. Since I actually increment by 2, we could start somewhat lower.</font> - Test_le(void) - : Test(1) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ <= %d\n</font>", max_threads_)); - } - - <font color=red>// Try out <font color=#008888>Condition::operator</font>+=(int)</font> - <font color=red>// This will cause the third thread to satisfy the condition.</font> - void modify(void) - { - condition_ += 2; - } - - <font color=red>// while( value <= max_threads_ ) wait();</font> - void test(void) - { - condition_ <= max_threads_; - } -}; - -<font color=red>/* For our final test, we'll go after <font color=#008888>Condition::operator</font>=(Condition::Compare) - By deriving from <font color=#008888>Condition::Compare</font> we can perform any arbitrary - test on the value of the condition variable. - */</font> -class Test_fo : public Test -{ -public: - <font color=red>// We'll be using operator*=(int) to increment the condition</font> - <font color=red>// variable, so we need to start with a non-zero value.</font> - Test_fo(void) - : Test(1) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ == FunctionObject\n</font>" )); - } - - <font color=red>// Double the value for each thread that we have.</font> - void modify(void) - { - condition_ *= 2; - } - - <font color=red>/* Derive our CompareFunction and provide the operator() that - performs our test. In this case, we'll compare the value to - the number 32. - */</font> - class CompareFunction : public <font color=#008888>Condition::Compare</font> - { - public: - <font color=red>// When this returns non-zero, the condition test operator</font> - <font color=red>// will unblock in each thread.</font> - int operator() ( <font color=#008888>Condition::value_t</font> _value ) - { - return _value == 32; - } - }; - - <font color=red>// Create the CompareFunction and wait for the condition variable </font> - <font color=red>// to reach the state we want.</font> - void test(void) - { - CompareFunction compare; - condition_ == compare; - } -}; - -<font color=red>/* In main() we just instantiate each of the four test objects that we - created. After open()ing each, we wait() for it's threads to exit. - */</font> -int main(int, char **) -{ - Test_ne test_ne; - test_ne.open(); - test_ne.wait(); - - Test_ge test_ge; - test_ge.open(); - test_ge.wait(); - - Test_le test_le; - test_le.open(); - test_le.wait(); - - Test_fo test_fo; - test_fo.open(); - test_fo.wait(); - - return(0); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/016/page05.html b/docs/tutorials/016/page05.html deleted file mode 100644 index c8aeb988a5e..00000000000 --- a/docs/tutorials/016/page05.html +++ /dev/null @@ -1,30 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And that's all... -<P> -For general use, it would make sense to convert Condition into a -template and get rid of some of the operators that don't make sense. -Using an integer as the condition type probably isn't realistic since -you could just use a semaphore or barrier for that case. Still, the -Tutorial shows the basics and provides a foundation on which you can -create a more useful class for your application. -<P> -<UL> -<LI><A HREF="Condition_i.h">Condition_i.h</A> -<LI><A HREF="Condition_i.cpp">Condition_i.cpp</A> -<LI><A HREF="condition.cpp">condition.cpp</A> -<LI><A HREF="Makefile">Makefile</A> -</UL><P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/017/017.dsp b/docs/tutorials/017/017.dsp deleted file mode 100644 index 932599a7a46..00000000000 --- a/docs/tutorials/017/017.dsp +++ /dev/null @@ -1,108 +0,0 @@ -# Microsoft Developer Studio Project File - Name="017" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=017 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "017.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "017.mak" CFG="017 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "017 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "017 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "017 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "017 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"barrier.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "017 - Win32 Release"
-# Name "017 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\barrier.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Barrier_i.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\Barrier_i.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/017/Barrier_i.cpp b/docs/tutorials/017/Barrier_i.cpp deleted file mode 100644 index a763c1d8273..00000000000 --- a/docs/tutorials/017/Barrier_i.cpp +++ /dev/null @@ -1,125 +0,0 @@ - -// $Id$ - -#include "Barrier_i.h" - -/* Initialize the threads_ count to zero and the barrier_ pointer to a - safe value. At the same time, we remember the thread that created - us so that we can allow it to change the thread count. -*/ -Barrier::Barrier(void) - : threads_(0) - ,barrier_(0) -{ - owner_ = ACE_OS::thr_self(); -} - -/* Ensure that barrier_ get's deleted so that we don't have a memory leak. - */ -Barrier::~Barrier(void) -{ - delete barrier_; -} - -// Report on the number of threads. -u_int Barrier::threads(void) -{ - return threads_.value(); -} - -/* Allow the owning thread to (re)set the number of threads. - make_barrier() is called because it will wait() if we were already - configured. Typical usage would be for the worker threads to - wait() while the primary (eg -- owner) thread adjusts the thread - count. - - For instance: - In the worker threads: - if( myBarrier.threads() != current_thread_count ) - myBarrier.wait(); - - In the primary thread: - if( myBarrier.threads() != current_thread_count ) - myBarrier.threads( current_thread_count, 1 ); - */ -int Barrier::threads( u_int _threads, int _wait ) -{ - if( ACE_OS::thr_self() != owner_ ) - { - return -1; - } - - threads_ = _threads; - - return make_barrier(_wait); -} - -/* Wait for all threads to synch if the thread count is valid. Note - that barrier_ will be 0 if the threads() mutator has not been - invoked. -*/ -int Barrier::wait(void) -{ - if( ! barrier_ ) - { - return -1; - } - - return barrier_->wait(); -} - -/* Wait for all threads to synch. As each thread passes wait(), it - will decrement our thread counter. (That is why we had to make - threads_ an atomic op.) When the last thread decrements the - counter it will also delete the ACE_Barrier & free up a little - memory. -*/ -int Barrier::done(void) -{ - if( this->wait() == -1 ) - { - return -1; - } - - --threads_; - - if( ! threads_.value() ) - { - delete barrier_; - barrier_ = 0; - } - - return 0; -} - -/* This will build the actual barrier. I broke this code out of the - threads() mutator in case it might be useful elsewhere. - If a barrier already exists, we will wait for all threads before - creating a new one. This trait is what allows the threads mutator - to be used as shown above. - */ -int Barrier::make_barrier( int _wait ) -{ - // Wait for and delete any existing barrier. - if( barrier_ ) - { - if( _wait ) - { - barrier_->wait(); - } - delete barrier_; - } - - // Ensure we have a valid thread count. - if( ! threads_.value() ) - { - return -1; - } - - // Create the actual barrier. Note that we initialize it with - // threads_.value() to set its internal thread count. If the - // 'new' fails we will return -1 to the caller. - ACE_NEW_RETURN(barrier_,ACE_Barrier(threads_.value()),-1); - - return 0; -} diff --git a/docs/tutorials/017/Barrier_i.h b/docs/tutorials/017/Barrier_i.h deleted file mode 100644 index 49c862cfd3d..00000000000 --- a/docs/tutorials/017/Barrier_i.h +++ /dev/null @@ -1,59 +0,0 @@ - -// $Id$ - -#ifndef BARRIER_H -#define BARRIER_H - -#include "ace/Synch.h" - -/* Barrier is a simple wrapper for the ACE_Barrier synchronization - class. The ACE_Barrier is already pretty easy to use but I thought - I'd wrap it up to create just a bit more abstraction at the - application level. - */ -class Barrier -{ -public: - // Basic constructor and destructor. If you only need to - // synch the start of your threads, you can safely delete your - // Barrier object after invoking done(). Of course, you - // should be careful to only delete the object once! - Barrier(void); - ~Barrier(void); - - // Set and get the number of threads that the barrier will - // manage. If you add or remove threads to your application - // at run-time you can use the mutator to reflect that - // change. Note, however, that you can only do that from the - // thread which first created the Barrier. (This is a - // limitation of my Barrier object, not the ACE_Barrier.) - // The optional _wait parameter will cause wait() to be - // invoked if there is already a valid threads value. - int threads( u_int _threads, int _wait = 0); - u_int threads(void); - - // Wait for all threads to reach the point where this is - // invoked. Because of the snappy way in which ACE_Barrier is - // implemented, you can invoke these back-to-back with no ill-effects. - int wait(void); - - // done() will invoke wait(). Before returning though, it - // will delete the barrier_ pointer below to reclaim some memory. - int done(void); - -protected: - // The number of threads we're synching - ACE_Atomic_Op<ACE_Mutex,u_int> threads_; - - // The ACE_Barrier that does all of the work - ACE_Barrier * barrier_; - - // The thread which created the Barrier in the first place. - // Only this thread can change the threads_ value. - ACE_thread_t owner_; - - // An internal method that constructs the barrier_ as needed. - int make_barrier( int _wait ); -}; - -#endif // BARRIER_H diff --git a/docs/tutorials/017/Makefile b/docs/tutorials/017/Makefile deleted file mode 100644 index 0830f114d68..00000000000 --- a/docs/tutorials/017/Makefile +++ /dev/null @@ -1,74 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = barrier - -FILES = Barrier_i - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../007/fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre > combine.shar && rm -f hdr bodies *.pre - -UNSHAR : # - sh combine.shar - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/017/barrier.cpp b/docs/tutorials/017/barrier.cpp deleted file mode 100644 index 287c3c8be8a..00000000000 --- a/docs/tutorials/017/barrier.cpp +++ /dev/null @@ -1,129 +0,0 @@ - -// $Id$ - -#include "Barrier_i.h" -#include "ace/Task.h" - -/* We'll use a simple Task<> derivative to test our new Barrier - object. -*/ -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - - // Open the object with a few threads - int open(int _threads); - - // Perform the test - int svc(void); - -protected: - // The Barrier object we'll use in our tests below - Barrier barrier_; -}; - -/* As usual, our open() will create one or more threads where we'll do - the interesting work. -*/ -int Test::open( int _threads ) -{ - // One thing about the barrier: You have to tell it how many - // threads it will be synching. The threads() mutator on my - // Barrier class lets you do that and hides the implementation - // details at the same time. - barrier_.threads(_threads); - - // Activate the tasks as usual... - return this->activate(THR_NEW_LWP, _threads); -} - -/* svc() will execute in each thread & do a few things with the - Barrier we have. - */ -int Test::svc(void) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Entry\n")); - - // Initialize the random number generator. We'll use this to - // create sleep() times in each thread. This will help us see - // if the barrier synch is working. - ACE_RANDR_TYPE seed = ACE_OS::thr_self(); - ACE_OS::srand(seed); - int delay; - - // After saying hello above, sleep for a random amount of time - // from 1 to 6 seconds. That will cause the next message - // "Entering wait()" to be staggered on the output as each - // thread's sleep() returns. - delay = ACE_OS::rand_r(seed)%5; - ACE_OS::sleep(abs(delay)+1); - - // When executing the app you should see these messages - // staggered in an at-most 6 second window. That is, you - // won't likely see them all at once. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Entering wait()\n")); - - // All of the threads will now wait at this point. As each - // thread finishes the sleep() above it will join the waiters. - if( barrier_.wait() == -1 ) - { - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tbarrier_.wait() failed!\n")); - return 0; - } - - // When all threads have reached wait() they will give us this - // message. If you execute this, you should see all of the - // "Everybody together" messages at about the same time. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Everybody together?\n")); - - // Now we do the sleep() cycle again... - delay = ACE_OS::rand_r(seed)%5; - ACE_OS::sleep(abs(delay)+1); - - // As before, these will trickle in over a few seconds. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Entering done()\n")); - - // This time we call done() instead of wait(). done() - // actually invokes wait() but before returning here, it will - // clean up a few resources. The goal is to prevent carrying - // around objects you don't need. - if( barrier_.wait() == -1 ) - { - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tbarrier_.done() failed!\n")); - return 0; - } - - // Since done() invokes wait() internally, we'll see this - // message from each thread simultaneously - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Is everyone still here?\n")); - - // A final sleep() - delay = ACE_OS::rand_r(seed)%5; - ACE_OS::sleep(abs(delay)+1); - - // These should be randomly spaced like all of the other - // post-sleep messages. - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() Chaos and anarchy for all!\n")); - - return(0); -} - -/* Our test application... - */ -int main(int, char**) -{ - // Create the test object - Test test; - - // and open it with 10 threads. - test.open(10); - // Now wait for them all to exit. - test.wait(); - - // Re-open the Test object with just 5 threads - test.open(5); - // and wait for them to complete also. - test.wait(); - - return(0); -} diff --git a/docs/tutorials/017/combine.shar b/docs/tutorials/017/combine.shar deleted file mode 100644 index 7e826ed7928..00000000000 --- a/docs/tutorials/017/combine.shar +++ /dev/null @@ -1,304 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-11-10 14:42 EST by <jcej@caldera.lads.com>. -# Source directory was `/scsiA/home/jcej/projects/ACE_wrappers/docs/tutorials/017'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 422 -rw-rw-r-- hdr -# 44 -rw-rw-r-- bodies -# 843 -rw-rw-r-- page01.pre -# 419 -rw-rw-r-- page02.pre -# 739 -rw-rw-r-- page03.pre -# 478 -rw-rw-r-- page04.pre -# 375 -rw-rw-r-- page05.pre -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh01874; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1110144198 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -9991b747f6aff75784cbeb88a79c06fc hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 422 -eq "$shar_count" || - $echo 'hdr:' 'original size' '422,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -barrier.cpp -Barrier_i.h -Barrier_i.cpp -SHAR_EOF - $shar_touch -am 1110144198 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -1b7c57aab2c61f845219723b8558bea6 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 44 -eq "$shar_count" || - $echo 'bodies:' 'original size' '44,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -The ACE_Barrier implements the barrier synchronization pattern. -<P> -That's nice. What does it mean? -<P> -What it means is that you can use the ACE_Barrier to cause a set of -threads to all wait at a specific point in your application. In other -words: the threads reach a barrier that none can pass until all are -present. -<P> -This would typically be used in scientific applications where a set of -threads are all working in parallel on some great computation but they -have to synch and summarize before continuing to the next stage of calculation. With -proper use of ACE_Barrier, the threads can easily synch before -continuing. -<P> -In this tutorial I'll create a simple wrapper for the ACE_Barrier. In -reality, the ACE_Barrier is so easy that a wrapper isn't really -needed. I created the wrapper anyway though just because I wanted to. -SHAR_EOF - $shar_touch -am 1110144198 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -30840e2b3e8bf84d94abb9177bffbbec page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 843 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '843,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -First, lets take a look at the main() routine and how it will use the -Barrier wrapper class. A simple ACE_Task derivative is used so that -we can perform work in multiple threads. These threads will use the -barrier to synch in a couple of places. -<P> -Obviously this isn't a very realistic example but you should be able -to get the idea of how to use a Barrier without getting hung up in -application-level details. -<HR> -SHAR_EOF - $shar_touch -am 1110144198 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -72dd8d286e36d8911945824bf2c91cc3 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 419 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '419,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -The Barrier class used by the test task is a simple wrapper around -ACE_Barrier. One of the things about ACE_Barrier is that you have to -tell it how many threads it will be managing. Since that number -usually isn't known when you create your Task derivative, you have to -dynamically allocate the ACE_Barrier. My Barrier wrapper takes care -of that for you and even provides for a clean way to delete the -ACE_Barrier instance if you want to save a few bytes. -<P> -An interesting extension of this Barrier class would be to wrap it up -in a smart pointer. You could then have the Barrier destructor invoke -wait() as a now-protected method. The result would allow you to treat -the Barrier object almost as a "synchronization guard". -<HR> -SHAR_EOF - $shar_touch -am 1110144198 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -6fc63f76eb4ac94dd6a8b45393613e7c page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 739 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '739,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -The Barrier implementation is quite simple. The threads() mutator -took a couple of tries to get right. In particular, be sure you know -when to apply the _wait paramter and when not to! In fact, the -requirement that only the "owning" thread can change the thread count -is rather limiting. A more appropriate solution would allow any -thread to safely change the count but that would require more complex -locking that is just a bit more than what I wanted to present here. -<HR> -SHAR_EOF - $shar_touch -am 1110144198 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -bed05089cb64c075cceec277e2a7da5f page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 478 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '478,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -Well, that's it for the simple Barrier Tutorial. I encourage you to -try it out and see what you like and dislike. Any improvements or -enhancements will gladly be integrated into the Tutorial. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="barrier.cpp">barrier.cpp</A> -<LI><A HREF="Barrier_i.h">Barrier_i.h</A> -<LI><A HREF="Barrier_i.cpp">Barrier_i.cpp</A> -</UL> -SHAR_EOF - $shar_touch -am 1110144198 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -616a2293adddb11896d28c7172436a65 page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 375 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '375,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh01874 -exit 0 diff --git a/docs/tutorials/017/page01.html b/docs/tutorials/017/page01.html deleted file mode 100644 index 5486ecbf66a..00000000000 --- a/docs/tutorials/017/page01.html +++ /dev/null @@ -1,34 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The ACE_Barrier implements the barrier synchronization pattern. -<P> -That's nice. What does it mean? -<P> -What it means is that you can use the ACE_Barrier to cause a set of -threads to all wait at a specific point in your application. In other -words: the threads reach a barrier that none can pass until all are -present. -<P> -This would typically be used in scientific applications where a set of -threads are all working in parallel on some great computation but they -have to synch and summarize before continuing to the next stage of calculation. With -proper use of ACE_Barrier, the threads can easily synch before -continuing. -<P> -In this tutorial I'll create a simple wrapper for the ACE_Barrier. In -reality, the ACE_Barrier is so easy that a wrapper isn't really -needed. I created the wrapper anyway though just because I wanted to. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/017/page02.html b/docs/tutorials/017/page02.html deleted file mode 100644 index 63617a76a8c..00000000000 --- a/docs/tutorials/017/page02.html +++ /dev/null @@ -1,156 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -First, lets take a look at the main() routine and how it will use the -Barrier wrapper class. A simple ACE_Task derivative is used so that -we can perform work in multiple threads. These threads will use the -barrier to synch in a couple of places. -<P> -Obviously this isn't a very realistic example but you should be able -to get the idea of how to use a Barrier without getting hung up in -application-level details. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Barrier_i.h</font>" -<font color=blue>#include</font> "<font color=green>ace/Task.h</font>" - -<font color=red>/* We'll use a simple Task<> derivative to test our new Barrier - object. -*/</font> -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - - <font color=red>// Open the object with a few threads</font> - int open(int _threads); - - <font color=red>// Perform the test</font> - int svc(void); - -protected: - <font color=red>// The Barrier object we'll use in our tests below</font> - Barrier barrier_; -}; - -<font color=red>/* As usual, our open() will create one or more threads where we'll do - the interesting work. -*/</font> -int <font color=#008888>Test::open</font>( int _threads ) -{ - <font color=red>// One thing about the barrier: You have to tell it how many</font> - <font color=red>// threads it will be synching. The threads() mutator on my</font> - <font color=red>// Barrier class lets you do that and hides the implementation </font> - <font color=red>// details at the same time.</font> - barrier_.threads(_threads); - - <font color=red>// Activate the tasks as usual...</font> - return this->activate(THR_NEW_LWP, _threads); -} - -<font color=red>/* svc() will execute in each thread & do a few things with the - Barrier we have. - */</font> -int <font color=#008888>Test::svc</font>(void) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Entry\n</font>")); - - <font color=red>// Initialize the random number generator. We'll use this to</font> - <font color=red>// create sleep() times in each thread. This will help us see </font> - <font color=red>// if the barrier synch is working.</font> - ACE_RANDR_TYPE seed = <font color=#008888>ACE_OS::thr_self</font>(); - <font color=#008888>ACE_OS::srand</font>(seed); - int delay; - - <font color=red>// After saying hello above, sleep for a random amount of time </font> - <font color=red>// from 1 to 6 seconds. That will cause the next message</font> - <font color=red>// "<font color=green>Entering wait()</font>" to be staggered on the output as each</font> - <font color=red>// thread's sleep() returns.</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%5; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - <font color=red>// When executing the app you should see these messages</font> - <font color=red>// staggered in an at-most 6 second window. That is, you</font> - <font color=red>// won't likely see them all at once.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Entering wait()\n</font>")); - - <font color=red>// All of the threads will now wait at this point. As each</font> - <font color=red>// thread finishes the sleep() above it will join the waiters.</font> - if( barrier_.wait() == -1 ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\tbarrier_.wait() failed!\n</font>")); - return 0; - } - - <font color=red>// When all threads have reached wait() they will give us this </font> - <font color=red>// message. If you execute this, you should see all of the</font> - <font color=red>// "<font color=green>Everybody together</font>" messages at about the same time.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Everybody together?\n</font>")); - - <font color=red>// Now we do the sleep() cycle again...</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%5; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - <font color=red>// As before, these will trickle in over a few seconds.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Entering done()\n</font>")); - - <font color=red>// This time we call done() instead of wait(). done()</font> - <font color=red>// actually invokes wait() but before returning here, it will </font> - <font color=red>// clean up a few resources. The goal is to prevent carrying</font> - <font color=red>// around objects you don't need.</font> - if( barrier_.wait() == -1 ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\tbarrier_.done() failed!\n</font>")); - return 0; - } - - <font color=red>// Since done() invokes wait() internally, we'll see this</font> - <font color=red>// message from each thread simultaneously</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Is everyone still here?\n</font>")); - - <font color=red>// A final sleep()</font> - delay = <font color=#008888>ACE_OS::rand_r</font>(seed)%5; - <font color=#008888>ACE_OS::sleep</font>(abs(delay)+1); - - <font color=red>// These should be randomly spaced like all of the other</font> - <font color=red>// post-sleep messages.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() Chaos and anarchy for all!\n</font>")); - - return(0); -} - -<font color=red>/* Our test application... - */</font> -int main(int, char**) -{ - <font color=red>// Create the test object</font> - Test test; - - <font color=red>// and open it with 10 threads.</font> - test.open(10); - <font color=red>// Now wait for them all to exit.</font> - test.wait(); - - <font color=red>// Re-open the Test object with just 5 threads</font> - test.open(5); - <font color=red>// and wait for them to complete also.</font> - test.wait(); - - return(0); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/017/page03.html b/docs/tutorials/017/page03.html deleted file mode 100644 index 6da527bbdb8..00000000000 --- a/docs/tutorials/017/page03.html +++ /dev/null @@ -1,90 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Barrier class used by the test task is a simple wrapper around -ACE_Barrier. One of the things about ACE_Barrier is that you have to -tell it how many threads it will be managing. Since that number -usually isn't known when you create your Task derivative, you have to -dynamically allocate the ACE_Barrier. My Barrier wrapper takes care -of that for you and even provides for a clean way to delete the -ACE_Barrier instance if you want to save a few bytes. -<P> -An interesting extension of this Barrier class would be to wrap it up -in a smart pointer. You could then have the Barrier destructor invoke -wait() as a now-protected method. The result would allow you to treat -the Barrier object almost as a "synchronization guard". -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>BARRIER_H</font> -<font color=blue>#define</font> <font color=purple>BARRIER_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Synch.h</font>" - -<font color=red>/* Barrier is a simple wrapper for the ACE_Barrier synchronization - class. The ACE_Barrier is already pretty easy to use but I thought - I'd wrap it up to create just a bit more abstraction at the - application level. - */</font> -class Barrier -{ -public: - <font color=red>// Basic constructor and destructor. If you only need to</font> - <font color=red>// synch the start of your threads, you can safely delete your </font> - <font color=red>// Barrier object after invoking done(). Of course, you</font> - <font color=red>// should be careful to only delete the object once!</font> - Barrier(void); - ~Barrier(void); - - <font color=red>// Set and get the number of threads that the barrier will</font> - <font color=red>// manage. If you add or remove threads to your application</font> - <font color=red>// at run-time you can use the mutator to reflect that</font> - <font color=red>// change. Note, however, that you can only do that from the</font> - <font color=red>// thread which first created the Barrier. (This is a</font> - <font color=red>// limitation of my Barrier object, not the ACE_Barrier.)</font> - <font color=red>// The optional _wait parameter will cause wait() to be</font> - <font color=red>// invoked if there is already a valid threads value.</font> - int threads( u_int _threads, int _wait = 0); - u_int threads(void); - - <font color=red>// Wait for all threads to reach the point where this is</font> - <font color=red>// invoked. Because of the snappy way in which ACE_Barrier is </font> - <font color=red>// implemented, you can invoke these back-to-back with no ill-effects.</font> - int wait(void); - - <font color=red>// done() will invoke wait(). Before returning though, it</font> - <font color=red>// will delete the barrier_ pointer below to reclaim some memory.</font> - int done(void); - -protected: - <font color=red>// The number of threads we're synching</font> - ACE_Atomic_Op<ACE_Mutex,u_int> threads_; - - <font color=red>// The ACE_Barrier that does all of the work</font> - ACE_Barrier * barrier_; - - <font color=red>// The thread which created the Barrier in the first place.</font> - <font color=red>// Only this thread can change the threads_ value.</font> - ACE_thread_t owner_; - - <font color=red>// An internal method that constructs the barrier_ as needed.</font> - int make_barrier( int _wait ); -}; - -<font color=blue>#endif</font> <font color=red>// BARRIER_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/017/page04.html b/docs/tutorials/017/page04.html deleted file mode 100644 index aced1b67217..00000000000 --- a/docs/tutorials/017/page04.html +++ /dev/null @@ -1,151 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The Barrier implementation is quite simple. The threads() mutator -took a couple of tries to get right. In particular, be sure you know -when to apply the _wait paramter and when not to! In fact, the -requirement that only the "owning" thread can change the thread count -is rather limiting. A more appropriate solution would allow any -thread to safely change the count but that would require more complex -locking that is just a bit more than what I wanted to present here. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Barrier_i.h</font>" - -<font color=red>/* Initialize the threads_ count to zero and the barrier_ pointer to a - safe value. At the same time, we remember the thread that created - us so that we can allow it to change the thread count. -*/</font> -<font color=#008888>Barrier::Barrier</font>(void) - : threads_(0) - ,barrier_(0) -{ - owner_ = <font color=#008888>ACE_OS::thr_self</font>(); -} - -<font color=red>/* Ensure that barrier_ get's deleted so that we don't have a memory leak. - */</font> -<font color=#008888>Barrier::~Barrier</font>(void) -{ - delete barrier_; -} - -<font color=red>// Report on the number of threads.</font> -u_int <font color=#008888>Barrier::threads</font>(void) -{ - return threads_.value(); -} - -<font color=red>/* Allow the owning thread to (re)set the number of threads. - make_barrier() is called because it will wait() if we were already - configured. Typical usage would be for the worker threads to - wait() while the primary (eg -- owner) thread adjusts the thread - count. - - For instance: - In the worker threads: - if( myBarrier.threads() != current_thread_count ) - myBarrier.wait(); - - In the primary thread: - if( myBarrier.threads() != current_thread_count ) - myBarrier.threads( current_thread_count, 1 ); - */</font> -int <font color=#008888>Barrier::threads</font>( u_int _threads, int _wait ) -{ - if( <font color=#008888>ACE_OS::thr_self</font>() != owner_ ) - { - return -1; - } - - threads_ = _threads; - - return make_barrier(_wait); -} - -<font color=red>/* Wait for all threads to synch if the thread count is valid. Note - that barrier_ will be 0 if the threads() mutator has not been - invoked. -*/</font> -int <font color=#008888>Barrier::wait</font>(void) -{ - if( ! barrier_ ) - { - return -1; - } - - return barrier_->wait(); -} - -<font color=red>/* Wait for all threads to synch. As each thread passes wait(), it - will decrement our thread counter. (That is why we had to make - threads_ an atomic op.) When the last thread decrements the - counter it will also delete the ACE_Barrier & free up a little - memory. -*/</font> -int <font color=#008888>Barrier::done</font>(void) -{ - if( this->wait() == -1 ) - { - return -1; - } - - --threads_; - - if( ! threads_.value() ) - { - delete barrier_; - barrier_ = 0; - } - - return 0; -} - -<font color=red>/* This will build the actual barrier. I broke this code out of the - threads() mutator in case it might be useful elsewhere. - If a barrier already exists, we will wait for all threads before - creating a new one. This trait is what allows the threads mutator - to be used as shown above. - */</font> -int <font color=#008888>Barrier::make_barrier</font>( int _wait ) -{ - <font color=red>// Wait for and delete any existing barrier.</font> - if( barrier_ ) - { - if( _wait ) - { - barrier_->wait(); - } - delete barrier_; - } - - <font color=red>// Ensure we have a valid thread count.</font> - if( ! threads_.value() ) - { - return -1; - } - - <font color=red>// Create the actual barrier. Note that we initialize it with </font> - <font color=red>// threads_.value() to set its internal thread count. If the</font> - <font color=red>// 'new' fails we will return -1 to the caller.</font> - ACE_NEW_RETURN(barrier_,ACE_Barrier(threads_.value()),-1); - - return 0; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/017/page05.html b/docs/tutorials/017/page05.html deleted file mode 100644 index f0fd213c487..00000000000 --- a/docs/tutorials/017/page05.html +++ /dev/null @@ -1,26 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 017</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 017</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Using the ACE_Barrier synch object</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Well, that's it for the simple Barrier Tutorial. I encourage you to -try it out and see what you like and dislike. Any improvements or -enhancements will gladly be integrated into the Tutorial. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="barrier.cpp">barrier.cpp</A> -<LI><A HREF="Barrier_i.h">Barrier_i.h</A> -<LI><A HREF="Barrier_i.cpp">Barrier_i.cpp</A> -</UL> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/018/018.dsp b/docs/tutorials/018/018.dsp deleted file mode 100644 index cf22bcbfaba..00000000000 --- a/docs/tutorials/018/018.dsp +++ /dev/null @@ -1,116 +0,0 @@ -# Microsoft Developer Studio Project File - Name="018" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=018 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "018.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "018.mak" CFG="018 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "018 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "018 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "018 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "018 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"token.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "018 - Win32 Release"
-# Name "018 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\Test_T.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\token.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\Mutex_i.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Test_T.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Token_i.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/018/Makefile b/docs/tutorials/018/Makefile deleted file mode 100644 index b4bd131c4cd..00000000000 --- a/docs/tutorials/018/Makefile +++ /dev/null @@ -1,74 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = token - -FILES = - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre > combine.shar && rm -f hdr bodies *.pre - -UNSHAR : # - sh combine.shar - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/018/Mutex_i.h b/docs/tutorials/018/Mutex_i.h deleted file mode 100644 index a017dd72888..00000000000 --- a/docs/tutorials/018/Mutex_i.h +++ /dev/null @@ -1,20 +0,0 @@ - -// $Id$ - -#ifndef MUTEX_I_H -#define MUTEX_I_H - -#include "Test_T.h" - -/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */ -class Mutex : public Test_T<ACE_Mutex> -{ -public: - Mutex(void) - : Test_T<ACE_Mutex>("Mutex") - {} -}; - -#endif // MUTEX_I_H diff --git a/docs/tutorials/018/Test_T.cpp b/docs/tutorials/018/Test_T.cpp deleted file mode 100644 index dfb01939d19..00000000000 --- a/docs/tutorials/018/Test_T.cpp +++ /dev/null @@ -1,191 +0,0 @@ - -// $Id$ - -/* This is something new... Since we're included by the header, we - have to provide a sentry to protect against recursive inclusion. - */ -#ifndef TEST_T_C -#define TEST_T_C - -// Get our definition -#include "Test_T.h" - -// We'll hard-code the thread count. Mucking around with that isn't -// really the point of the exercise today... -#define TEST_THREAD_COUNT 5 - -/* Construction time... - Initialize the baseclass, the name and the barrier. Since the - client will probably invoke run() next, we go ahead an announce our - creation to make the output more readable. - */ -template <class MUTEX> -Test_T<MUTEX>::Test_T( const char * _name ) - : ACE_Task<ACE_MT_SYNCH>() - ,name_(_name) - ,barrier_(TEST_THREAD_COUNT) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest_T (%s) created\n", _name )); -} - -/* Activate the threads and create some test data... - */ -template <class MUTEX> -int Test_T<MUTEX>::run(void) -{ - // Try to activate the set of threads that will test the mutex - if( this->open() == -1 ) - { - return -1; - } - - // Create a set of messages. I chose twice the thread count - // so that we can see how they get distributed. - for( int i = 0 ; i < TEST_THREAD_COUNT*2 ; ++i ) - { - // A message block big enough for a simple message. - ACE_Message_Block * message = new ACE_Message_Block(64); - - // Put some text into the message block so that we can - // know what's going on when we get to svc() - sprintf(message->wr_ptr(),"Message Number %d",i); - message->wr_ptr( strlen(message->rd_ptr())+1 ); - - // Send the message to the thread pool - if( this->send(message) == -1 ) - { - break; - } - } - - // Send a hangup to the thread pool so that we can exit. - if( this->send() == -1 ) - { - return -1; - } - - // Wait for all of the threads to exit and then return to the client. - return this->wait(); -} - -/* Send a message to the thread pool - */ -template <class MUTEX> -int Test_T<MUTEX>::send( ACE_Message_Block * _message ) -{ - // If no message was provided, create a hangup message. - if( ! _message ) - { - _message = new - ACE_Message_Block(0,ACE_Message_Block::MB_HANGUP); - } - - // Use the duplicate() method when sending the message. For - // this simple application, that may be overkill but it's a - // good habit. duplicate() will increment the reference count - // so that each user of the message can release() it when - // done. The last user to call release() will cause the data - // to be deleted. - if( this->putq(_message->duplicate()) == -1 ) - { - // Error? release() the message block and return failure. - _message->release(); - return -1; - } - - // release() the data to prevent memory leaks. - _message->release(); - - return 0; -} - -/* A farily typical open(). Just activate the set of threads and return. - */ -template <class MUTEX> -int Test_T<MUTEX>::open( void * _arg ) -{ - ACE_UNUSED_ARG(_arg); - return this->activate(THR_NEW_LWP, TEST_THREAD_COUNT); -} - -/* svc() is also fairly typical. The new part is the use of the guard - to simulate protection of shared resources. - */ -template <class MUTEX> -int Test_T<MUTEX>::svc(void) -{ - // Keep a simple thread identifier. We could always use the - // thread id but this is a nice, simple number. - int my_number = ++thread_num_; - - ACE_DEBUG ((LM_INFO, "%d (%P|%t|%T)\tTest_T::svc() Entry\n", - my_number)); - - // Wait for all of threads to get started so that they all - // have a fair shot at the message queue. Comment this out - // and see how the behaviour changes. Does it surprise you? - barrier_.wait(); - - ACE_Message_Block * message; - int mcount = 0; - - // This would usually be an almost-infinite loop. Instead, - // I've governed it so that no single thread can get more than - // "thread count" number of messages. You'll see that with - // ACE_Mutex, this is just about the only way to keep the - // first thread from getting all the action. Ths is obviously - // just for sake of the test since you don't want your - // real-world app to exit after a fixed number of messages! - while( mcount < TEST_THREAD_COUNT ) - { - // Get a message. Since the message queue is already - // thread-safe we don't have to guard it. In fact, moving - // the guard up above getq() will decrease your - // parallelization. - if( getq(message) == -1 ) - { - break; - } - - // Now we pretend that there are shared resources required - // to process the data. We grab the mutex through the - // guard and "do work". In a real application, you'll - // want to keep these critical sections as small as - // possible since they will reduce the usefulness of - // multi-threading. - guard_t guard(mutex_); - - // Increase our message count for the debug output and the - // governor. - ++mcount; - - // Check for a hangup request... - // Notice the use of release() again to prevent leaks - if( message->msg_type() == ACE_Message_Block::MB_HANGUP ) - { - message->release(); - break; - } - - // Display the message so that we can see if things are - // working the way we want. - ACE_DEBUG ((LM_INFO, "%d (%P|%t|%T)\tTest_T::svc() received message #%d (%s)\n", - my_number,mcount,message->rd_ptr())); - - // Pretend that the work takes some time to complete. - // Remember, we're holding that lock during this time! - ACE_OS::sleep(1); - - // No leaks... - message->release(); - } - - // Send a hangup to the other threads in the pool. If we don't - // do this then wait() will never exit since all of the other - // threads are still blocked on getq(). - this->send(); - - return(0); -}; - -#endif // TEST_T_C diff --git a/docs/tutorials/018/Test_T.h b/docs/tutorials/018/Test_T.h deleted file mode 100644 index 47e0f0a118c..00000000000 --- a/docs/tutorials/018/Test_T.h +++ /dev/null @@ -1,78 +0,0 @@ - -// $Id$ - -#ifndef TEST_T_H -#define TEST_T_H - -#include "ace/Task.h" - -/* We'll create a simple ACE_Task derivative for testing a couple of - different locking mechanisms. We've hidden the open() method to - force our client into using the run() method instead. - - The naming convention *_T is fairly typical for ACE. The _T suffix - on the object name (and it's source files) indicates that this is a - templated class. Generally, there is a non-templated class defined - also such as foobar.h that would be included instead of foobar_T.h. - */ -template <class MUTEX> -class Test_T : public ACE_Task<ACE_MT_SYNCH> -{ -public: - // Allow our derivative to name the class so that we can tell - // the user what's going on as we test the lock. - Test_T( const char * _name ); - - // This will run the entire test. open() will be called to - // activate the task's threads. We then add a number of - // messages to the queue for svc() to process. - int run(void); - -protected: - - // Activate a few threads - int open( void * _arg = 0 ); - // Read some things from the message queue and exercise the - // lock. - int svc( void ); - // Send a message block to svc(). If _message is 0 then send - // a shutdown request (e.g., MB_HANGUP) - int send( ACE_Message_Block * _message = 0 ); - - // The object's name. Typically provided by a derivative. - const char * name_; - // We want to barrier the svc() methods to give all of the - // threads a fair chance - ACE_Barrier barrier_; - - // As each thread enters svc() it will increment this. While - // we have a thread id available to us, I wanted a simple - // value to display in debug messages. - ACE_Atomic_Op<ACE_Mutex,int> thread_num_; - - // Set our mutex type based on the template parameter. We - // then build a guard type based on that type. - typedef MUTEX mutex_t; - typedef ACE_Guard<mutex_t> guard_t; - - // Our mutex. We'll use this in svc() to protect imaginary - // shared resources. - mutex_t mutex_; -}; - -/* Although different compilers differ in their details, almost all of - them require that you provide the definition of the templated - object along with the declaration. With any luck, this will change - someday & we'll have smaller object files. Until then, the lines - below will take care of you. - */ - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "Test_T.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation "Test_T.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#endif // TEST_T_H diff --git a/docs/tutorials/018/Token_i.h b/docs/tutorials/018/Token_i.h deleted file mode 100644 index 2be3707aae3..00000000000 --- a/docs/tutorials/018/Token_i.h +++ /dev/null @@ -1,23 +0,0 @@ - -// $Id$ - -#ifndef TOKEN_I_H -#define TOKEN_I_H - -#include "Test_T.h" - -// Go get ace/Token.h so that we know what an ACE_Token is. -#include "ace/Token.h" - -/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */ -class Token : public Test_T<ACE_Token> -{ -public: - Token(void) - : Test_T<ACE_Token>("Token") - {} -}; - -#endif // TOKEN_I_H diff --git a/docs/tutorials/018/combine.shar b/docs/tutorials/018/combine.shar deleted file mode 100644 index 5db5d69e58f..00000000000 --- a/docs/tutorials/018/combine.shar +++ /dev/null @@ -1,419 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-11-15 12:38 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/018'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 416 -rw-rw-r-- hdr -# 64 -rw-rw-r-- bodies -# 1446 -rw-rw-r-- page01.pre -# 430 -rw-rw-r-- page02.pre -# 1282 -rw-rw-r-- page03.pre -# 689 -rw-rw-r-- page04.pre -# 260 -rw-rw-r-- page05.pre -# 1523 -rw-rw-r-- page06.pre -# 478 -rw-rw-r-- page07.pre -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh11947; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1114141798 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -66dbcd27e23cdcc9c230089e9c289bcb hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 416 -eq "$shar_count" || - $echo 'hdr:' 'original size' '416,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -token.cpp -Test_T.h -Test_T.cpp -Token_i.h Mutex_i.h -output -SHAR_EOF - $shar_touch -am 1114165298 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -22e70b25b6f23655b44d31fcf1a669f8 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 64 -eq "$shar_count" || - $echo 'bodies:' 'original size' '64,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X -Welcome to Tutorial 18! -<P> -We've seen various ACE methods for synchronization in this and other -tutorial sections. Something we haven't yet seen is the ACE_Token. -ACE_Token has a really cool thing: it behaves in a FIFO manner. -<P> -Why is that cool? -<P> -In the other tutorials, you may have found that one thread will end up -with all of the work. Even though other threads are available, the OS -scheduling and lock management just causes it to happen. With -ACE_Token, the threads are queued up on the token and served in a -traditional first-in-first-out manner. -<P> -Why is FIFO important? -<P> -Well, if your app is running in a bunch of threads and each is doing -the same thing on the local host then FIFO may not be important. -However, take the case where each thread is connected to a remote -system. Let's say you have a dozen threads in your app and each is -connected to a different remote system. Each of the threads will be -given a block of data which will be passed to the remote for some -intense calculation. If you use the FIFO then you'll spread the work -more-or-less evenly between the remote peers. If you use the -traditional mutex then one peer may get the lion's share of the work. -<P> -It gets down to a personal decision based on the application's needs. -Consider your application, examine its behavior & decide for yourself -if you want to spread the work evenly or if it's OK to let some -threads work harder than others. -SHAR_EOF - $shar_touch -am 1114142998 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -d420fe795c2d1e13cc4a9b4972ba1b47 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 1446 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '1446,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -Our main() just keeps getting simpler! I guess that's a good thing. -<P> -What we've done is create two Task-derived objects that test different -locking mechanisms. The Token object uses ACE_Token and the Mutex -object uses ACE_Mutex. When you execute the application you should -see quite a difference in thread utilization. At the end of the -tutorial I've included a link to the output of a typical run of the -application. -<HR> -SHAR_EOF - $shar_touch -am 1114153698 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -a36353959f7874c8e31884d2acd7eb43 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 430 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '430,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -Our Test object is a simple derivative of ACE_Task. Although we've -certainly used templates in other tutorials, this is the first time -we've created one of our own. -<P> -In a lot of ways, you can think of templates as the sophisticated -cousin of the old C-style pre-processor macros. With templates, -however, you get better type-checking and much easier debugging. There -are certainly other benefits but these are my favorites. -<P> -Our template's MUTEX parameter is used to set the mutex type -<i>mutex_t</i>. That'll be used in svc() so that we can protect -shared resources needed during the processing of data received on our -message queue. -<P> -Note at the bottom how we have to include the <i>cpp</i> file -associated with us. Most compilers have to see the definition of -templated classes along with their declaration. You might be tempted, -therefore, to just put the definitions in the header file. Resist -that temptation because templates are one of the fastest growing areas -of compilers. Including the definition like we do here leads to long -compile times and overly-large binaries. With luck, the compilers -will get smarter in the future and we won't need definition -inclusion. If you've already got them broken out then you'll save -yourself a lot of time! -<HR> -SHAR_EOF - $shar_touch -am 1114154698 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -4f59a65824406215b1d28b2335b9c691 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 1282 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '1282,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -Our Test implementation looks much like the other ACE_Task derivatives -we've used in the past. The most obvious change is the addition of -the run() method. run() will activate the threads and put a few -messages into the queue. We could have done that in main() but it -just makes more sense here. -<P> -Notice how svc() grabs the guard after getting a message from the -queue. Since we constructed our Task baseclass with ACE_MT_SYNCH, we -know that the queue is already thread-safe. Our purpose in grabbing -the additional lock is to show how ACE_Token and ACE_Mutex behave -differently. In a real app, you'd be doing this to protect shared -resources that the threads might clobber. -<HR> -SHAR_EOF - $shar_touch -am 1114161298 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -428df54cf8483880bfcace604cd9ae3c page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 689 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '689,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -Here we create simple derivatives of our Test templated class. Each -is parameterized with our mutex of choice and "named". Using the Test -template we're able to reuse all of the code with practially no -retyping and certainly much less chance of error! -<HR> -SHAR_EOF - $shar_touch -am 1114161298 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -8f427c59ed060b06d99dfa81e0447454 page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 260 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '260,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -That's it for the code, now let's take a quick look at some output. -The first set of output is from the Token test, the second is Mutex -test. Notice how the threads are evenly utilized in the Token test. -Each thread gets to see exactly two messages. There's also an -interesting side-effect that the messages are processed in order. (You -can't rely on that, it just happend in this particular run.) -<P> -With the Mutex test, however, we see that the first thread gets no -less than 1/2 of all messages. In fact, if we didn't have the -governor in svc() it might have gotten them all! -<P> -Why does this happen? -<P> -Primarily because of time slicing. Even though each thread takes time -to do work (1 second in our test), it can still own the timeslice when -it gets back to the mutex acquire. Since the other threads are still -switched out, the current thread regets the lock and continues. On -the other hand, the ACE_Token is very careful about the order in which -the acquisition is allowed and more evenly distributes the work. -<P> -Play around with the sleep() call in svc(). You'll find that as you -decrease it, there is more chance that even the Token test will do -most of its work in one thread. You're still at the mercy of the OS -time slicing. In reality, though, it will take a moment or two for -work to be done. The end goal isn't necessarily to distribute the -work evenly over all threads but, rather, to distribute it evenly -among <i>available</i> threads. The distinction is subtle but important. -<HR> -SHAR_EOF - $shar_touch -am 1114162298 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pre:' 'MD5 check failed' -9a4cc7f2ddce9c585a86113da4f5eb8d page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 1523 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '1523,' 'current size' "$shar_count!" - fi -fi -# ============= page07.pre ============== -if test -f 'page07.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page07.pre' '(file already exists)' -else - $echo 'x -' extracting 'page07.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page07.pre' && -And now we're at the end of another Tutorial. As always, feel free to -send in questions and comments. There are certainly more -implementation possibilites and I'll gladly integrate yours into these -Tutorials. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="token.cpp">token.cpp</A> -<LI><A HREF="Test.h">Test.h</A> -<LI><A HREF="Test.cpp">Test.cpp</A> -<LI><A HREF="Token_i.h">Token_i.h</A> -<LI><A HREF="Mutex_i.h">Mutex_i.h</A> -<LI><A HREF="output">output</A> -</UL> -SHAR_EOF - $shar_touch -am 1114162598 'page07.pre' && - chmod 0664 'page07.pre' || - $echo 'restore of' 'page07.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page07.pre:' 'MD5 check failed' -e1a201541e51dd42654d31440eb4f36c page07.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page07.pre'`" - test 478 -eq "$shar_count" || - $echo 'page07.pre:' 'original size' '478,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh11947 -exit 0 diff --git a/docs/tutorials/018/output b/docs/tutorials/018/output deleted file mode 100644 index b292728e4d6..00000000000 --- a/docs/tutorials/018/output +++ /dev/null @@ -1,33 +0,0 @@ -(21386|1024|15:26:32.366520) Test (Token) created -1 (21386|1025|15:26:32.390340) Test::svc() Entry -2 (21386|2050|15:26:32.408330) Test::svc() Entry -3 (21386|3075|15:26:32.427363) Test::svc() Entry -4 (21386|4100|15:26:32.447285) Test::svc() Entry -5 (21386|5125|15:26:32.482479) Test::svc() Entry -1 (21386|1025|15:26:32.498583) Test::svc() received message #1 (Message Number 0) -2 (21386|2050|15:26:33.517770) Test::svc() received message #1 (Message Number 1) -3 (21386|3075|15:26:34.537701) Test::svc() received message #1 (Message Number 2) -4 (21386|4100|15:26:35.557675) Test::svc() received message #1 (Message Number 3) -5 (21386|5125|15:26:36.577650) Test::svc() received message #1 (Message Number 4) -1 (21386|1025|15:26:37.597689) Test::svc() received message #2 (Message Number 5) -2 (21386|2050|15:26:38.607689) Test::svc() received message #2 (Message Number 6) -3 (21386|3075|15:26:39.617675) Test::svc() received message #2 (Message Number 7) -4 (21386|4100|15:26:40.637653) Test::svc() received message #2 (Message Number 8) -5 (21386|5125|15:26:41.657637) Test::svc() received message #2 (Message Number 9) - -(21386|1024|15:26:42.679919) Test (Mutex) created -1 (21386|6150|15:26:42.700301) Test::svc() Entry -2 (21386|7175|15:26:42.737413) Test::svc() Entry -3 (21386|8200|15:26:42.754241) Test::svc() Entry -4 (21386|9225|15:26:42.772122) Test::svc() Entry -5 (21386|10250|15:26:42.788867) Test::svc() Entry -1 (21386|6150|15:26:42.806260) Test::svc() received message #1 (Message Number 0) -1 (21386|6150|15:26:43.807539) Test::svc() received message #2 (Message Number 5) -1 (21386|6150|15:26:44.817569) Test::svc() received message #3 (Message Number 6) -1 (21386|6150|15:26:45.827571) Test::svc() received message #4 (Message Number 7) -1 (21386|6150|15:26:46.837581) Test::svc() received message #5 (Message Number 8) -2 (21386|7175|15:26:47.847908) Test::svc() received message #1 (Message Number 1) -2 (21386|7175|15:26:48.857555) Test::svc() received message #2 (Message Number 9) -4 (21386|9225|15:26:49.867991) Test::svc() received message #1 (Message Number 3) -3 (21386|8200|15:26:50.887559) Test::svc() received message #1 (Message Number 2) -5 (21386|10250|15:26:51.898275) Test::svc() received message #1 (Message Number 4) diff --git a/docs/tutorials/018/page01.html b/docs/tutorials/018/page01.html deleted file mode 100644 index 03ce2accfd1..00000000000 --- a/docs/tutorials/018/page01.html +++ /dev/null @@ -1,47 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - -Welcome to Tutorial 18! -<P> -We've seen various ACE methods for synchronization in this and other -tutorial sections. Something we haven't yet seen is the ACE_Token. -ACE_Token has a really cool thing: it behaves in a FIFO manner. -<P> -Why is that cool? -<P> -In the other tutorials, you may have found that one thread will end up -with all of the work. Even though other threads are available, the OS -scheduling and lock management just causes it to happen. With -ACE_Token, the threads are queued up on the token and served in a -traditional first-in-first-out manner. -<P> -Why is FIFO important? -<P> -Well, if your app is running in a bunch of threads and each is doing -the same thing on the local host then FIFO may not be important. -However, take the case where each thread is connected to a remote -system. Let's say you have a dozen threads in your app and each is -connected to a different remote system. Each of the threads will be -given a block of data which will be passed to the remote for some -intense calculation. If you use the FIFO then you'll spread the work -more-or-less evenly between the remote peers. If you use the -traditional mutex then one peer may get the lion's share of the work. -<P> -It gets down to a personal decision based on the application's needs. -Consider your application, examine its behavior & decide for yourself -if you want to spread the work evenly or if it's OK to let some -threads work harder than others. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/018/page02.html b/docs/tutorials/018/page02.html deleted file mode 100644 index 691e8613e5f..00000000000 --- a/docs/tutorials/018/page02.html +++ /dev/null @@ -1,46 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Our main() just keeps getting simpler! I guess that's a good thing. -<P> -What we've done is create two Task-derived objects that test different -locking mechanisms. The Token object uses ACE_Token and the Mutex -object uses ACE_Mutex. When you execute the application you should -see quite a difference in thread utilization. At the end of the -tutorial I've included a link to the output of a typical run of the -application. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// Get our two Test derivatives...</font> -<font color=blue>#include</font> "<font color=green>Token_i.h</font>" -<font color=blue>#include</font> "<font color=green>Mutex_i.h</font>" - -int main(int,char**) -{ - <font color=red>// See what an ACE_Token does for us.</font> - Token token; - token.run(); - - <font color=red>// And now and ACE_Mutex.</font> - Mutex mutex; - mutex.run(); - - return(0); -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/018/page03.html b/docs/tutorials/018/page03.html deleted file mode 100644 index e94b8b9c844..00000000000 --- a/docs/tutorials/018/page03.html +++ /dev/null @@ -1,121 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Our Test object is a simple derivative of ACE_Task. Although we've -certainly used templates in other tutorials, this is the first time -we've created one of our own. -<P> -In a lot of ways, you can think of templates as the sophisticated -cousin of the old C-style pre-processor macros. With templates, -however, you get better type-checking and much easier debugging. There -are certainly other benefits but these are my favorites. -<P> -Our template's MUTEX parameter is used to set the mutex type -<i>mutex_t</i>. That'll be used in svc() so that we can protect -shared resources needed during the processing of data received on our -message queue. -<P> -Note at the bottom how we have to include the <i>cpp</i> file -associated with us. Most compilers have to see the definition of -templated classes along with their declaration. You might be tempted, -therefore, to just put the definitions in the header file. Resist -that temptation because templates are one of the fastest growing areas -of compilers. Including the definition like we do here leads to long -compile times and overly-large binaries. With luck, the compilers -will get smarter in the future and we won't need definition -inclusion. If you've already got them broken out then you'll save -yourself a lot of time! -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>TEST_T_H</font> -<font color=blue>#define</font> <font color=purple>TEST_T_H</font> - -<font color=blue>#include</font> "<font color=green>ace/Task.h</font>" - -<font color=red>/* We'll create a simple ACE_Task derivative for testing a couple of - different locking mechanisms. We've hidden the open() method to - force our client into using the run() method instead. - - The naming convention *_T is fairly typical for ACE. The _T suffix - on the object name (and it's source files) indicates that this is a - templated class. Generally, there is a non-templated class defined - also such as foobar.h that would be included instead of foobar_T.h. - */</font> -template <class MUTEX> -class Test_T : public ACE_Task<ACE_MT_SYNCH> -{ -public: - <font color=red>// Allow our derivative to name the class so that we can tell</font> - <font color=red>// the user what's going on as we test the lock.</font> - Test_T( const char * _name ); - - <font color=red>// This will run the entire test. open() will be called to</font> - <font color=red>// activate the task's threads. We then add a number of</font> - <font color=red>// messages to the queue for svc() to process.</font> - int run(void); - -protected: - - <font color=red>// Activate a few threads</font> - int open( void * _arg = 0 ); - <font color=red>// Read some things from the message queue and exercise the</font> - <font color=red>// lock.</font> - int svc( void ); - <font color=red>// Send a message block to svc(). If _message is 0 then send</font> - <font color=red>// a shutdown request (e.g., MB_HANGUP)</font> - int send( ACE_Message_Block * _message = 0 ); - - <font color=red>// The object's name. Typically provided by a derivative.</font> - const char * name_; - <font color=red>// We want to barrier the svc() methods to give all of the</font> - <font color=red>// threads a fair chance</font> - ACE_Barrier barrier_; - - <font color=red>// As each thread enters svc() it will increment this. While</font> - <font color=red>// we have a thread id available to us, I wanted a simple</font> - <font color=red>// value to display in debug messages.</font> - ACE_Atomic_Op<ACE_Mutex,int> thread_num_; - - <font color=red>// Set our mutex type based on the template parameter. We</font> - <font color=red>// then build a guard type based on that type.</font> - typedef MUTEX mutex_t; - typedef ACE_Guard<mutex_t> guard_t; - - <font color=red>// Our mutex. We'll use this in svc() to protect imaginary</font> - <font color=red>// shared resources.</font> - mutex_t mutex_; -}; - -<font color=red>/* Although different compilers differ in their details, almost all of - them require that you provide the definition of the templated - object along with the declaration. With any luck, this will change - someday & we'll have smaller object files. Until then, the lines - below will take care of you. - */</font> - -<font color=blue>#if defined</font> (<font color=purple>ACE_TEMPLATES_REQUIRE_SOURCE</font>) -<font color=blue>#include</font> "<font color=green>Test_T.cpp</font>" -<font color=blue>#endif</font> <font color=red>/* ACE_TEMPLATES_REQUIRE_SOURCE */</font> - -<font color=blue>#if defined</font> (<font color=purple>ACE_TEMPLATES_REQUIRE_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>implementation</font> ("<font color=green>Test_T.cpp</font>") -<font color=blue>#endif</font> <font color=red>/* ACE_TEMPLATES_REQUIRE_PRAGMA */</font> - -<font color=blue>#endif</font> <font color=red>// TEST_T_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/018/page04.html b/docs/tutorials/018/page04.html deleted file mode 100644 index dcf0ac3ca2b..00000000000 --- a/docs/tutorials/018/page04.html +++ /dev/null @@ -1,222 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Our Test implementation looks much like the other ACE_Task derivatives -we've used in the past. The most obvious change is the addition of -the run() method. run() will activate the threads and put a few -messages into the queue. We could have done that in main() but it -just makes more sense here. -<P> -Notice how svc() grabs the guard after getting a message from the -queue. Since we constructed our Task baseclass with ACE_MT_SYNCH, we -know that the queue is already thread-safe. Our purpose in grabbing -the additional lock is to show how ACE_Token and ACE_Mutex behave -differently. In a real app, you'd be doing this to protect shared -resources that the threads might clobber. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>/* This is something new... Since we're included by the header, we - have to provide a sentry to protect against recursive inclusion. - */</font> -<font color=blue>#ifndef</font> <font color=purple>TEST_T_C</font> -<font color=blue>#define</font> <font color=purple>TEST_T_C</font> - -<font color=red>// Get our definition</font> -<font color=blue>#include</font> "<font color=green>Test_T.h</font>" - -<font color=red>// We'll hard-code the thread count. Mucking around with that isn't</font> -<font color=red>// really the point of the exercise today...</font> -<font color=blue>#define</font> <font color=purple>TEST_THREAD_COUNT</font> 5 - -<font color=red>/* Construction time... - Initialize the baseclass, the name and the barrier. Since the - client will probably invoke run() next, we go ahead an announce our - creation to make the output more readable. - */</font> -template <class MUTEX> -Test_T<MUTEX>::Test_T( const char * _name ) - : ACE_Task<ACE_MT_SYNCH>() - ,name_(_name) - ,barrier_(TEST_THREAD_COUNT) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\tTest_T (%s) created\n</font>", _name )); -} - -<font color=red>/* Activate the threads and create some test data... - */</font> -template <class MUTEX> -int Test_T<MUTEX>::run(void) -{ - <font color=red>// Try to activate the set of threads that will test the mutex</font> - if( this->open() == -1 ) - { - return -1; - } - - <font color=red>// Create a set of messages. I chose twice the thread count</font> - <font color=red>// so that we can see how they get distributed.</font> - for( int i = 0 ; i < TEST_THREAD_COUNT*2 ; ++i ) - { - <font color=red>// A message block big enough for a simple message.</font> - ACE_Message_Block * message = new ACE_Message_Block(64); - - <font color=red>// Put some text into the message block so that we can</font> - <font color=red>// know what's going on when we get to svc()</font> - sprintf(message->wr_ptr(),"<font color=green>Message Number %d</font>",i); - message->wr_ptr( strlen(message->rd_ptr())+1 ); - - <font color=red>// Send the message to the thread pool</font> - if( this->send(message) == -1 ) - { - break; - } - } - - <font color=red>// Send a hangup to the thread pool so that we can exit.</font> - if( this->send() == -1 ) - { - return -1; - } - - <font color=red>// Wait for all of the threads to exit and then return to the client.</font> - return this->wait(); -} - -<font color=red>/* Send a message to the thread pool - */</font> -template <class MUTEX> -int Test_T<MUTEX>::send( ACE_Message_Block * _message ) -{ - <font color=red>// If no message was provided, create a hangup message.</font> - if( ! _message ) - { - _message = new - ACE_Message_Block(0,<font color=#008888>ACE_Message_Block::MB_HANGUP</font>); - } - - <font color=red>// Use the duplicate() method when sending the message. For</font> - <font color=red>// this simple application, that may be overkill but it's a</font> - <font color=red>// good habit. duplicate() will increment the reference count </font> - <font color=red>// so that each user of the message can release() it when</font> - <font color=red>// done. The last user to call release() will cause the data</font> - <font color=red>// to be deleted.</font> - if( this->putq(_message->duplicate()) == -1 ) - { - <font color=red>// Error? release() the message block and return failure.</font> - _message->release(); - return -1; - } - - <font color=red>// release() the data to prevent memory leaks.</font> - _message->release(); - - return 0; -} - -<font color=red>/* A farily typical open(). Just activate the set of threads and return. - */</font> -template <class MUTEX> -int Test_T<MUTEX>::open( void * _arg ) -{ - ACE_UNUSED_ARG(_arg); - return this->activate(THR_NEW_LWP, TEST_THREAD_COUNT); -} - -<font color=red>/* svc() is also fairly typical. The new part is the use of the guard - to simulate protection of shared resources. - */</font> -template <class MUTEX> -int Test_T<MUTEX>::svc(void) -{ - <font color=red>// Keep a simple thread identifier. We could always use the</font> - <font color=red>// thread id but this is a nice, simple number.</font> - int my_number = ++thread_num_; - - ACE_DEBUG ((LM_INFO, "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() Entry\n</font>", - my_number)); - - <font color=red>// Wait for all of threads to get started so that they all</font> - <font color=red>// have a fair shot at the message queue. Comment this out</font> - <font color=red>// and see how the behaviour changes. Does it surprise you?</font> - barrier_.wait(); - - ACE_Message_Block * message; - int mcount = 0; - - <font color=red>// This would usually be an almost-infinite loop. Instead,</font> - <font color=red>// I've governed it so that no single thread can get more than </font> - <font color=red>// "<font color=green>thread count</font>" number of messages. You'll see that with</font> - <font color=red>// ACE_Mutex, this is just about the only way to keep the</font> - <font color=red>// first thread from getting all the action. Ths is obviously </font> - <font color=red>// just for sake of the test since you don't want your</font> - <font color=red>// real-world app to exit after a fixed number of messages!</font> - while( mcount < TEST_THREAD_COUNT ) - { - <font color=red>// Get a message. Since the message queue is already</font> - <font color=red>// thread-safe we don't have to guard it. In fact, moving </font> - <font color=red>// the guard up above getq() will decrease your</font> - <font color=red>// parallelization.</font> - if( getq(message) == -1 ) - { - break; - } - - <font color=red>// Now we pretend that there are shared resources required </font> - <font color=red>// to process the data. We grab the mutex through the</font> - <font color=red>// guard and "<font color=green>do work</font>". In a real application, you'll</font> - <font color=red>// want to keep these critical sections as small as</font> - <font color=red>// possible since they will reduce the usefulness of</font> - <font color=red>// multi-threading.</font> - guard_t guard(mutex_); - - <font color=red>// Increase our message count for the debug output and the</font> - <font color=red>// governor.</font> - ++mcount; - - <font color=red>// Check for a hangup request...</font> - <font color=red>// Notice the use of release() again to prevent leaks</font> - if( message->msg_type() == <font color=#008888>ACE_Message_Block::MB_HANGUP</font> ) - { - message->release(); - break; - } - - <font color=red>// Display the message so that we can see if things are</font> - <font color=red>// working the way we want.</font> - ACE_DEBUG ((LM_INFO, "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() received message #%d (%s)\n</font>", - my_number,mcount,message->rd_ptr())); - - <font color=red>// Pretend that the work takes some time to complete.</font> - <font color=red>// Remember, we're holding that lock during this time!</font> - <font color=#008888>ACE_OS::sleep</font>(1); - - <font color=red>// No leaks...</font> - message->release(); - } - - <font color=red>// Send a hangup to the other threads in the pool. If we don't</font> - <font color=red>// do this then wait() will never exit since all of the other</font> - <font color=red>// threads are still blocked on getq().</font> - this->send(); - - return(0); -}; - -<font color=blue>#endif</font> <font color=red>// TEST_T_C</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/018/page05.html b/docs/tutorials/018/page05.html deleted file mode 100644 index 7d78a18cae0..00000000000 --- a/docs/tutorials/018/page05.html +++ /dev/null @@ -1,70 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Here we create simple derivatives of our Test templated class. Each -is parameterized with our mutex of choice and "named". Using the Test -template we're able to reuse all of the code with practially no -retyping and certainly much less chance of error! -<HR> -<PRE> -<HR width=50%><P><center>Token_i.h</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>TOKEN_I_H</font> -<font color=blue>#define</font> <font color=purple>TOKEN_I_H</font> - -<font color=blue>#include</font> "<font color=green>Test_T.h</font>" - -<font color=red>// Go get ace/Token.h so that we know what an ACE_Token is.</font> -<font color=blue>#include</font> "<font color=green>ace/Token.h</font>" - -<font color=red>/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */</font> -class Token : public Test_T<ACE_Token> -{ -public: - Token(void) - : Test_T<ACE_Token>("<font color=green>Token</font>") - {} -}; - -<font color=blue>#endif</font> <font color=red>// TOKEN_I_H</font> -</PRE> -<PRE> -<HR width=50%><P><center>Mutex_i.h</center><HR width=50%> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>MUTEX_I_H</font> -<font color=blue>#define</font> <font color=purple>MUTEX_I_H</font> - -<font color=blue>#include</font> "<font color=green>Test_T.h</font>" - -<font color=red>/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */</font> -class Mutex : public Test_T<ACE_Mutex> -{ -public: - Mutex(void) - : Test_T<ACE_Mutex>("<font color=green>Mutex</font>") - {} -}; - -<font color=blue>#endif</font> <font color=red>// MUTEX_I_H</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/018/page06.html b/docs/tutorials/018/page06.html deleted file mode 100644 index f26fa5a5452..00000000000 --- a/docs/tutorials/018/page06.html +++ /dev/null @@ -1,79 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -That's it for the code, now let's take a quick look at some output. -The first set of output is from the Token test, the second is Mutex -test. Notice how the threads are evenly utilized in the Token test. -Each thread gets to see exactly two messages. There's also an -interesting side-effect that the messages are processed in order. (You -can't rely on that, it just happend in this particular run.) -<P> -With the Mutex test, however, we see that the first thread gets no -less than 1/2 of all messages. In fact, if we didn't have the -governor in svc() it might have gotten them all! -<P> -Why does this happen? -<P> -Primarily because of time slicing. Even though each thread takes time -to do work (1 second in our test), it can still own the timeslice when -it gets back to the mutex acquire. Since the other threads are still -switched out, the current thread regets the lock and continues. On -the other hand, the ACE_Token is very careful about the order in which -the acquisition is allowed and more evenly distributes the work. -<P> -Play around with the sleep() call in svc(). You'll find that as you -decrease it, there is more chance that even the Token test will do -most of its work in one thread. You're still at the mercy of the OS -time slicing. In reality, though, it will take a moment or two for -work to be done. The end goal isn't necessarily to distribute the -work evenly over all threads but, rather, to distribute it evenly -among <i>available</i> threads. The distinction is subtle but important. -<HR> -<PRE> -(21386|1024|15:26:32.366520) Test (Token) created -1 (21386|1025|15:26:32.390340) <font color=#008888>Test::svc</font>() Entry -2 (21386|2050|15:26:32.408330) <font color=#008888>Test::svc</font>() Entry -3 (21386|3075|15:26:32.427363) <font color=#008888>Test::svc</font>() Entry -4 (21386|4100|15:26:32.447285) <font color=#008888>Test::svc</font>() Entry -5 (21386|5125|15:26:32.482479) <font color=#008888>Test::svc</font>() Entry -1 (21386|1025|15:26:32.498583) <font color=#008888>Test::svc</font>() received message #1 (Message Number 0) -2 (21386|2050|15:26:33.517770) <font color=#008888>Test::svc</font>() received message #1 (Message Number 1) -3 (21386|3075|15:26:34.537701) <font color=#008888>Test::svc</font>() received message #1 (Message Number 2) -4 (21386|4100|15:26:35.557675) <font color=#008888>Test::svc</font>() received message #1 (Message Number 3) -5 (21386|5125|15:26:36.577650) <font color=#008888>Test::svc</font>() received message #1 (Message Number 4) -1 (21386|1025|15:26:37.597689) <font color=#008888>Test::svc</font>() received message #2 (Message Number 5) -2 (21386|2050|15:26:38.607689) <font color=#008888>Test::svc</font>() received message #2 (Message Number 6) -3 (21386|3075|15:26:39.617675) <font color=#008888>Test::svc</font>() received message #2 (Message Number 7) -4 (21386|4100|15:26:40.637653) <font color=#008888>Test::svc</font>() received message #2 (Message Number 8) -5 (21386|5125|15:26:41.657637) <font color=#008888>Test::svc</font>() received message #2 (Message Number 9) - -(21386|1024|15:26:42.679919) Test (Mutex) created -1 (21386|6150|15:26:42.700301) <font color=#008888>Test::svc</font>() Entry -2 (21386|7175|15:26:42.737413) <font color=#008888>Test::svc</font>() Entry -3 (21386|8200|15:26:42.754241) <font color=#008888>Test::svc</font>() Entry -4 (21386|9225|15:26:42.772122) <font color=#008888>Test::svc</font>() Entry -5 (21386|10250|15:26:42.788867) <font color=#008888>Test::svc</font>() Entry -1 (21386|6150|15:26:42.806260) <font color=#008888>Test::svc</font>() received message #1 (Message Number 0) -1 (21386|6150|15:26:43.807539) <font color=#008888>Test::svc</font>() received message #2 (Message Number 5) -1 (21386|6150|15:26:44.817569) <font color=#008888>Test::svc</font>() received message #3 (Message Number 6) -1 (21386|6150|15:26:45.827571) <font color=#008888>Test::svc</font>() received message #4 (Message Number 7) -1 (21386|6150|15:26:46.837581) <font color=#008888>Test::svc</font>() received message #5 (Message Number 8) -2 (21386|7175|15:26:47.847908) <font color=#008888>Test::svc</font>() received message #1 (Message Number 1) -2 (21386|7175|15:26:48.857555) <font color=#008888>Test::svc</font>() received message #2 (Message Number 9) -4 (21386|9225|15:26:49.867991) <font color=#008888>Test::svc</font>() received message #1 (Message Number 3) -3 (21386|8200|15:26:50.887559) <font color=#008888>Test::svc</font>() received message #1 (Message Number 2) -5 (21386|10250|15:26:51.898275) <font color=#008888>Test::svc</font>() received message #1 (Message Number 4) -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page07.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/018/page07.html b/docs/tutorials/018/page07.html deleted file mode 100644 index 528df2ad61c..00000000000 --- a/docs/tutorials/018/page07.html +++ /dev/null @@ -1,30 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And now we're at the end of another Tutorial. As always, feel free to -send in questions and comments. There are certainly more -implementation possibilites and I'll gladly integrate yours into these -Tutorials. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="token.cpp">token.cpp</A> -<LI><A HREF="Test.h">Test.h</A> -<LI><A HREF="Test.cpp">Test.cpp</A> -<LI><A HREF="Token_i.h">Token_i.h</A> -<LI><A HREF="Mutex_i.h">Mutex_i.h</A> -<LI><A HREF="output">output</A> -</UL> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/018/token.cpp b/docs/tutorials/018/token.cpp deleted file mode 100644 index 995b127014f..00000000000 --- a/docs/tutorials/018/token.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -// $Id$ - -// Get our two Test derivatives... -#include "Token_i.h" -#include "Mutex_i.h" - -int main(int,char**) -{ - // See what an ACE_Token does for us. - Token token; - token.run(); - - // And now and ACE_Mutex. - Mutex mutex; - mutex.run(); - - return(0); -} diff --git a/docs/tutorials/019/019-client.dsp b/docs/tutorials/019/019-client.dsp deleted file mode 100644 index aae33177cd5..00000000000 --- a/docs/tutorials/019/019-client.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="019 client" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=019 client - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "019 client.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "019 client.mak" CFG="019 client - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "019 client - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "019 client - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "019 client - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "019 client - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "019 client - Win32 Release"
-# Name "019 client - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\client.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\shmem.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\shmem.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/019/019-client2.dsp b/docs/tutorials/019/019-client2.dsp deleted file mode 100644 index d1f6e685c92..00000000000 --- a/docs/tutorials/019/019-client2.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="019 client2" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=019 client2 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "019 client2.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "019 client2.mak" CFG="019 client2 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "019 client2 - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "019 client2 - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "019 client2 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "019 client2 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "019 client2 - Win32 Release"
-# Name "019 client2 - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\shmem.h
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\client2.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\shmem.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/019/019-server.dsp b/docs/tutorials/019/019-server.dsp deleted file mode 100644 index 789431e0ba8..00000000000 --- a/docs/tutorials/019/019-server.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="019 server" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=019 server - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "019 server.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "019 server.mak" CFG="019 server - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "019 server - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "019 server - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "019 server - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "019 server - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "019 server - Win32 Release"
-# Name "019 server - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\shmem.h
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\shmem.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/019/019-server2.dsp b/docs/tutorials/019/019-server2.dsp deleted file mode 100644 index f3b72b718a6..00000000000 --- a/docs/tutorials/019/019-server2.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="019 server2" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=019 server2 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "019 server2.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "019 server2.mak" CFG="019 server2 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "019 server2 - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "019 server2 - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "019 server2 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "019 server2 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "019 server2 - Win32 Release"
-# Name "019 server2 - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\shmem.h
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\server2.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\shmem.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/019/Makefile b/docs/tutorials/019/Makefile deleted file mode 100644 index 05d4917ee26..00000000000 --- a/docs/tutorials/019/Makefile +++ /dev/null @@ -1,76 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client server client2 server2 - -FILES = shmem - -BUILD = $(VBIN) - -BSRC = $(addsuffix .cpp,$(BIN)) - -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : # - $(MAKE) SRC="$(SRC) $(BSRC)" depend - perl ../fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre > combine.shar && rm -f hdr bodies *.pre - -UNSHAR : # - sh combine.shar - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/019/client.cpp b/docs/tutorials/019/client.cpp deleted file mode 100644 index f74a141183a..00000000000 --- a/docs/tutorials/019/client.cpp +++ /dev/null @@ -1,70 +0,0 @@ - -// $Id$ - -// Again, the common stuff -#include "shmem.h" - -#if defined(ACE_LACKS_SYSV_SHMEM) -int main (int, char *[]) -{ - ACE_ERROR_RETURN ((LM_ERROR, "System V Shared Memory not available on this platform\n"),100); -} -#else // ACE_LACKS_SYSV_SHMEM -int main (int, char *[]) -{ - /* - Attach ourselves to the shared memory segment. - */ - ACE_Shared_Memory_SV shm_client (SHM_KEY, SHMSZ); - - /* - Get our reference to the segment... - */ - char *shm = (char *) shm_client.malloc (); - - /* - If the segment identified by SHM_KEY didn't exist then we'll - get back a 0 from malloc(). You should do this check even - if you include the CREATE flag 'cause you never know when it - might fail. - */ - if( ! shm ) - { - ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) Could not get the segment!\n"),100); - } - - /* - Does this match what your server said? - */ - ACE_DEBUG ((LM_INFO, "(%P|%t) Shared Memory is at 0x%x\n", - shm )); - - /* - Show the shared data to the user and convert it all to - uppper-case along the way. - */ - for (char *s = shm; *s != '\0'; s++) - { - putchar (*s); - *s = toupper(*s); - } - - putchar ('\n'); - - /* - Flag the server that we're done. - */ - *shm = '*'; - - /* - Here, we use close() instead of remove(). Remember, that - will just remove our attachment to the segment. Look - closely at the 'nattch' column of the ipcs output & you'll - see that this decrements it by one. - */ - shm_client.close(); - - return 0; -} - -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/019/client2.cpp b/docs/tutorials/019/client2.cpp deleted file mode 100644 index fc212281a2f..00000000000 --- a/docs/tutorials/019/client2.cpp +++ /dev/null @@ -1,40 +0,0 @@ - -// $Id$ - -#include "shmem.h" - -#if defined(ACE_LACKS_SYSV_SHMEM) -int main (int, char *[]) -{ - ACE_ERROR_RETURN ((LM_ERROR, "System V Shared Memory not available on this platform\n"),100); -} -#else // ACE_LACKS_SYSV_SHMEM -int main (int, char *[]) -{ - ACE_Shared_Memory_SV shm_client (SHM_KEY, sizeof(SharedData)); - - char *shm = (char *) shm_client.malloc (); - - ACE_DEBUG ((LM_INFO, "(%P|%t) Shared Memory is at 0x%x\n", - shm )); - - /* - More placement new. The constructor parameter prevents - clobbering what the server may have written with it's show() - method. - */ - SharedData * sd = new(shm) SharedData(0); - - // Show it - sd->show(); - // Change it - sd->set(); - // Advertise it - sd->available(1); - - shm_client.close(); - - return 0; -} - -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/019/combine.shar b/docs/tutorials/019/combine.shar deleted file mode 100644 index 1b4fd263723..00000000000 --- a/docs/tutorials/019/combine.shar +++ /dev/null @@ -1,337 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-12-28 16:29 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/019'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 409 -rw-rw-r-- hdr -# 71 -rw-rw-r-- bodies -# 1161 -rw-rw-r-- page01.pre -# 563 -rw-rw-r-- page02.pre -# 219 -rw-rw-r-- page03.pre -# 676 -rw-rw-r-- page04.pre -# 178 -rw-rw-r-- page05.pre -# 401 -rw-rw-r-- page06.pre -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh06808; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 019</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1220184898 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -3b7d0df272c309b4b8d67d872956bae3 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 409 -eq "$shar_count" || - $echo 'hdr:' 'original size' '409,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -server.cpp -client.cpp -server2.cpp client2.cpp -shmem.h shmem.cpp -SHAR_EOF - $shar_touch -am 1228162198 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -7eebfcd7b463404b494b4c97107f9d14 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 71 -eq "$shar_count" || - $echo 'bodies:' 'original size' '71,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X Did you ever wish you could read someone's mind? Or that they could -X read yours? -X <p> -X Well, we won't be doing that here but we'll try to get close by -X letting your code do something similar: Shared Memory. -X <p> -X What we're going to do is ask the operating system to set -X aside a part of RAM that we can share with another process. By -X doing this, we can allow our applications to swap data very -X efficiently. -X <p> -X Along the way, we'll have to come up with some sort of -X coordintation betweent the processes. That is the most -X difficult part of a shared memory system. In the tutorial we're -X just going to take a simplistic approach (eg -- busy loop) but -X real-world applications will need to take a serious look at -X process-level synch mechanisms such as ACE_*_Semaphore. -X <P> -X Caveat: I've barely begun to use shared memory -X myself. This tutorial and the next are very simple-minded and -X primitive. Anyone who wants to provide more realistic -X replacements is encouraged to drop me a note -X (<A HREF="mailto:jcej@lads.com">jcej@lads.com</A>). -SHAR_EOF - $shar_touch -am 1228154598 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -aef26c91d7b1ff2212e955be7e2d6ab9 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 1161 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '1161,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -We'll first take a look at the server side. As ususal with -co-operating applications, you need the server up and running first. -In the case of shared memory applications, the server will create the -shared memory segment. In this example, it will also remove the -segment when done. It is important to realize though that the segment -can be created external to your application and can persist beyond -it's lifetime. In fact, you can use shared memory to create a layer -of persistence between application instances (at least, until the -machine comes down.) -<HR> -SHAR_EOF - $shar_touch -am 1228154698 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -f651adc7b68da0c21b92c8a665980a18 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 563 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '563,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -The client app looks much like the server. We could have included the -CREATE flag with no ill effects but note the use of close() instead of -remove(). Picking the correct detachment method is rather important! -<HR> -SHAR_EOF - $shar_touch -am 1228160398 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -d7658702d31436f5124bf4dbec330e69 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 219 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '219,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -X Before we move on to shmem.h, I want to show a different approach. In -X this new client/server pair, I use placement new to stuff an object -X (instead of a blob of bytes) into the shared memory segment. -X <P> -X There are a few caveats to putting objects into shared memory. The -X most important ones all deal with pointers: -X <ul> -X <li>Be sure your pointers point into the shared memory and not -X local process memory. -X <li>Only in very special cases will objects with virtual methods -X work (because of the VTable pointers). -X </ul> -<P> -That's not to say you shouldn't try... Just try carefully and test a lot! -X <HR> -SHAR_EOF - $shar_touch -am 1228160798 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -f34318496f39858e4ddadebe5647dfd2 page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 676 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '676,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -X Here's the mysterious shmem.h. I wanted to show it after the -X placement-new client and server so that the SharedData object -X would have some relevance. -X <HR> -SHAR_EOF - $shar_touch -am 1228162198 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -42f4ddae6f0ce1583d1dc03d5e485cba page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 178 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '178,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -X That's it! I warned you that this one was pretty primitive. -X -X <ul> -X <li><A HREF="server.cpp">server.cpp</A> -X <li><A HREF="client.cpp">client.cpp</A> -X <li><A HREF="server2.cpp">server2.cpp</A> -X <li><A HREF="client2.cpp">client2.cpp</A> -X <li><A HREF="shmem.h">shmem.h</A> -X <li><A HREF="shmem.cpp">shmem.cpp</A> -X <li><A HREF="Makefile">Makefile</A> -X </ul> -SHAR_EOF - $shar_touch -am 1228162998 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pre:' 'MD5 check failed' -6e3002889733f5e80e7f9cc945965955 page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 401 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '401,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh06808 -exit 0 diff --git a/docs/tutorials/019/page01.html b/docs/tutorials/019/page01.html deleted file mode 100644 index c4ab2a7d300..00000000000 --- a/docs/tutorials/019/page01.html +++ /dev/null @@ -1,38 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 019</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - Did you ever wish you could read someone's mind? Or that they could - read yours? - <p> - Well, we won't be doing that here but we'll try to get close by - letting your code do something similar: Shared Memory. - <p> - What we're going to do is ask the operating system to set - aside a part of RAM that we can share with another process. By - doing this, we can allow our applications to swap data very - efficiently. - <p> - Along the way, we'll have to come up with some sort of - coordintation betweent the processes. That is the most - difficult part of a shared memory system. In the tutorial we're - just going to take a simplistic approach (eg -- busy loop) but - real-world applications will need to take a serious look at - process-level synch mechanisms such as ACE_*_Semaphore. - <P> - Caveat: I've barely begun to use shared memory - myself. This tutorial and the next are very simple-minded and - primitive. Anyone who wants to provide more realistic - replacements is encouraged to drop me a note - (<A HREF="mailto:jcej@lads.com">jcej@lads.com</A>).<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/019/page02.html b/docs/tutorials/019/page02.html deleted file mode 100644 index d6a42dc8aef..00000000000 --- a/docs/tutorials/019/page02.html +++ /dev/null @@ -1,127 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 019</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -We'll first take a look at the server side. As ususal with -co-operating applications, you need the server up and running first. -In the case of shared memory applications, the server will create the -shared memory segment. In this example, it will also remove the -segment when done. It is important to realize though that the segment -can be created external to your application and can persist beyond -it's lifetime. In fact, you can use shared memory to create a layer -of persistence between application instances (at least, until the -machine comes down.) -<HR><PRE> - -<font color=red>/* - The client and server both need to know the shared memory key and - size. To prevent headaches, I've put those into a header they both - can share. - */</font> -<font color=blue>#include</font> "<font color=green>shmem.h</font>" - -int main (int, char *[]) -{ - <font color=red>/* - You can use the ACE_Malloc template to create memory pools - from various shared memory strategies. It's really cool. - We're not going to use it. - - Instead, I want to get to the roots of it all and directly - use ACE_Shared_Memory_SV. Like many ACE objects, this is a - wrapper around OS services. - - With this constructor we create a shared memory area to - use. The ACE_CREATE flag will cause it to be created if it - doesn't already exist. The SHM_KEY value (from shmem.h) - uniquely identifies the segment and allows other apps to - attach to the same segment. Execute 'ipcs -m' before and - after starting this app to see that the segment is created. - (I can't for the life of me correlate the SHM_KEY value back - to the key/id reported by ipcs though.) - */</font> - ACE_Shared_Memory_SV shm_server (SHM_KEY, SHMSZ, - <font color=#008888>ACE_Shared_Memory_SV::ACE_CREATE</font>); - - <font color=red>/* - The constructor created the segment for us but we still need - to map the segment into our address space. (Note that you - can pass a value to malloc() but it will be silently - igored.) The void* (cast to char*) that is returned will - point to the beginning of the shared segment. - */</font> - char *shm = (char *) shm_server.malloc (); - - <font color=red>/* - This second pointer will be used to walk through the block - of memory... - */</font> - char *s = shm; - - <font color=red>/* - Out of curiosity, I added this output message. The tests - I've done so far show me the same address for client and - server. What does your OS tell you? - */</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>", - shm )); - - <font color=red>/* - At this point, our application can use the pointer just like - any other given to us by new or malloc. For our purposes, - we'll copy in the alpabet as a null-terminated string. - */</font> - for (char c = 'a'; c <= 'z'; c++) - *s++ = c; - - *s = '\0'; - - <font color=red>/* - Using a simple not-too-busy loop, we'll wait for the client - (or anyone else) to change the first byte in the shared area - to a '*' character. This is where you would rather use - semaphores or some similar "<font color=green>resource light</font>" approach. - */</font> - while (*shm != '*') - <font color=#008888>ACE_OS::sleep</font> (1); - - <font color=red>/* - Let's see what the client did to the segment... - */</font> - for (char *s = shm; *s != '\0'; s++) - { - putchar (*s); - } - putchar ('\n'); - - <font color=red>/* - If you're done with the segment and ready for it to be - removed from the system, use the remove() method. Once the - program exits, do 'ipcs -m' again and you'll see that the - segment is gone. If you just want to terminate your use of - the segment but leave it around for other apps, use the - close() method instead. - - The free() method may be tempting but it doesn't actually do - anything. If your app is *really* done with the shared - memory then use either close() or remove(). - */</font> - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>remove</font>")); - - return 0; -} - -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/019/page03.html b/docs/tutorials/019/page03.html deleted file mode 100644 index 76a9c48229e..00000000000 --- a/docs/tutorials/019/page03.html +++ /dev/null @@ -1,83 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 019</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The client app looks much like the server. We could have included the -CREATE flag with no ill effects but note the use of close() instead of -remove(). Picking the correct detachment method is rather important! -<HR> -<PRE> - -<font color=red>// Again, the common stuff</font> -<font color=blue>#include</font> "<font color=green>shmem.h</font>" - -int main (int, char *[]) -{ - <font color=red>/* - Attach ourselves to the shared memory segment. - */</font> - ACE_Shared_Memory_SV shm_client (SHM_KEY, SHMSZ); - - <font color=red>/* - Get our reference to the segment... - */</font> - char *shm = (char *) shm_client.malloc (); - - <font color=red>/* - If the segment identified by SHM_KEY didn't exist then we'll - get back a 0 from malloc(). You should do this check even - if you include the CREATE flag 'cause you never know when it - might fail. - */</font> - if( ! shm ) - { - ACE_ERROR_RETURN ((LM_ERROR,"<font color=green>(%P|%t) Could not get the segment!\n</font>"),100); - } - - <font color=red>/* - Does this match what your server said? - */</font> - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>", - shm )); - - <font color=red>/* - Show the shared data to the user and convert it all to - uppper-case along the way. - */</font> - for (char *s = shm; *s != '\0'; s++) - { - putchar (*s); - *s = toupper(*s); - } - - putchar ('\n'); - - <font color=red>/* - Flag the server that we're done. - */</font> - *shm = '*'; - - <font color=red>/* - Here, we use close() instead of remove(). Remember, that - will just remove our attachment to the segment. Look - closely at the 'nattch' column of the ipcs output & you'll - see that this decrements it by one. - */</font> - shm_client.close(); - - return 0; -} - -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/019/page04.html b/docs/tutorials/019/page04.html deleted file mode 100644 index 635659e6204..00000000000 --- a/docs/tutorials/019/page04.html +++ /dev/null @@ -1,114 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 019</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - Before we move on to shmem.h, I want to show a different approach. In - this new client/server pair, I use placement new to stuff an object - (instead of a blob of bytes) into the shared memory segment. - <P> - There are a few caveats to putting objects into shared memory. The - most important ones all deal with pointers: - <ul> - <li>Be sure your pointers point into the shared memory and not - local process memory. - <li>Only in very special cases will objects with virtual methods - work (because of the VTable pointers). - </ul> -<P> -That's not to say you shouldn't try... Just try carefully and test a lot! - <HR> -<HR width=50%><P><center>server2.cpp</center><HR width=50%> -<PRE> - -<font color=blue>#include</font> "<font color=green>shmem.h</font>" - -int -main (int, char *[]) -{ - <font color=red>// Be sure the segment is sized to hold our object.</font> - ACE_Shared_Memory_SV shm_server (SHM_KEY, sizeof(SharedData), - <font color=#008888>ACE_Shared_Memory_SV::ACE_CREATE</font>); - - char *shm = (char *) shm_server.malloc (); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>", - shm )); - - <font color=red>/* - Use the placement new syntax to stuff the object into the - correct location. I think they generally reserve this for - the advanced class... - */</font> - SharedData * sd = new(shm) SharedData; - - <font color=red>// Use the set() method to put some data into the object</font> - sd->set(); - - <font color=red>// Set the 'available' flag to zero so that we can wait on it</font> - sd->available(0); - - <font color=red>/* - Another cheesy busy loop while we wait for the object to - become available. The cool way would be to hide a semaphore - or two behind this method call & eliminate the sleep. - */</font> - while ( ! sd->available() ) - <font color=#008888>ACE_OS::sleep</font> (1); - - <font color=red>// Show the user what's in the segment</font> - sd->show(); - - <font color=red>// All done.</font> - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>remove</font>")); - - return 0; -} - -</PRE> -<HR width=50%><P><center>client2.cpp</center><HR width=50%> -<PRE> - -<font color=blue>#include</font> "<font color=green>shmem.h</font>" - -int main (int, char *[]) -{ - ACE_Shared_Memory_SV shm_client (SHM_KEY, sizeof(SharedData)); - - char *shm = (char *) shm_client.malloc (); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>", - shm )); - - <font color=red>/* - More placement new. The constructor parameter prevents - clobbering what the server may have written with it's show() - method. - */</font> - SharedData * sd = new(shm) SharedData(0); - - <font color=red>// Show it</font> - sd->show(); - <font color=red>// Change it</font> - sd->set(); - <font color=red>// Advertise it</font> - sd->available(1); - - shm_client.close(); - - return 0; -} - -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/019/page05.html b/docs/tutorials/019/page05.html deleted file mode 100644 index b04217a9551..00000000000 --- a/docs/tutorials/019/page05.html +++ /dev/null @@ -1,112 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 019</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - Here's the mysterious shmem.h. I wanted to show it after the - placement-new client and server so that the SharedData object - would have some relevance. - <HR> -<HR width=50%><P><center>shmem.h</center><HR width=50%> -<PRE> - -<font color=blue>#ifndef</font> <font color=purple>SHMEM_H</font> -<font color=blue>#define</font> <font color=purple>SHMEM_H</font> - -<font color=red>// This is where you'll find the ACE_Shared_Memory_SV object</font> -<font color=blue>#include</font> "<font color=green>ace/Shared_Memory_SV.h</font>" - -<font color=red>// SHMSZ is just enough for the alphabet and a null terminator</font> -<font color=blue>#define</font> <font color=purple>SHMSZ</font> 27 - -<font color=red>// Play with this, pick a value you like that isn't used by something else.</font> -<font color=blue>#define</font> <font color=purple>SHM_KEY</font> 4200 - -<font color=red>/* - This is what we stuff into shared memory via placement new in the - second client/server pair. Notice that it is a very basic object - with no virtual methods and only concrete data. - */</font> -class SharedData -{ -public: - <font color=red>// Construct the object and optionally initialize buf_.</font> - SharedData(int _initialize = 1); - - <font color=red>// Put some data into buf_</font> - void set(void); - <font color=red>// Show the data in buf_</font> - void show(void); - <font color=red>// What is the value of available_</font> - int available(void); - <font color=red>// Set the value of available_</font> - void available(int _available); - -protected: - <font color=red>// Big enough for a simple message</font> - char buf_[128]; - <font color=red>// A cheap mutex</font> - int available_; -}; - -<font color=blue>#endif</font> <font color=red>// SHMEM_H</font> -</PRE> -<HR width=50%><P><center>shmem.cpp</center><HR width=50%> -<PRE> - -<font color=blue>#include</font> "<font color=green>shmem.h</font>" - -<font color=red>/* - Set the available_ flag to zero & optionally initialize the buf_ - area. -*/</font> -<font color=#008888>SharedData::SharedData</font>(int _initialize) - : available_(0) -{ - if( _initialize ) - { - <font color=#008888>ACE_OS::sprintf</font>(buf_,"<font color=green>UNSET\n</font>"); - } -} - -<font color=red>/* - Write the process ID into the buffer. This will prove to us that - the data really is shared between the client and server. -*/</font> -void <font color=#008888>SharedData::set</font>(void) -{ - <font color=#008888>ACE_OS::sprintf</font>(buf_,"<font color=green>My PID is (%d)\n</font>",ACE_OS::getpid()); -} - -<font color=red>/* - Display the buffer to the user -*/</font> -void <font color=#008888>SharedData::show</font>(void) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Data text is (%s)\n</font>", - buf_ )); -} - -<font color=red>// Show flag</font> -int <font color=#008888>SharedData::available</font>(void) -{ - return available_; -} - -<font color=red>// Set flag</font> -void <font color=#008888>SharedData::available</font>(int _available) -{ - available_ = _available; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/019/page06.html b/docs/tutorials/019/page06.html deleted file mode 100644 index 65b8c7ac7ca..00000000000 --- a/docs/tutorials/019/page06.html +++ /dev/null @@ -1,28 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 019</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 019</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - That's it! I warned you that this one was pretty primitive. - - <ul> - <li><A HREF="server.cpp">server.cpp</A> - <li><A HREF="client.cpp">client.cpp</A> - <li><A HREF="server2.cpp">server2.cpp</A> - <li><A HREF="client2.cpp">client2.cpp</A> - <li><A HREF="shmem.h">shmem.h</A> - <li><A HREF="shmem.cpp">shmem.cpp</A> - <li><A HREF="Makefile">Makefile</A> - </ul> - <HR> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/019/server.cpp b/docs/tutorials/019/server.cpp deleted file mode 100644 index fc869fb3fa2..00000000000 --- a/docs/tutorials/019/server.cpp +++ /dev/null @@ -1,123 +0,0 @@ - -// $Id$ - -/* - The client and server both need to know the shared memory key and - size. To prevent headaches, I've put those into a header they both - can share. - */ -#include "shmem.h" - -#if defined(ACE_LACKS_SYSV_SHMEM) -int main (int, char *[]) -{ - ACE_ERROR_RETURN ((LM_ERROR, "System V Shared Memory not available on this platform\n"),100); -} -#else // ACE_LACKS_SYSV_SHMEM -int main (int, char *argv[]) -{ - /* - You can use the ACE_Malloc template to create memory pools - from various shared memory strategies. It's really cool. - We're not going to use it. - - Instead, I want to get to the roots of it all and directly - use ACE_Shared_Memory_SV. Like many ACE objects, this is a - wrapper around OS services. - - With this constructor we create a shared memory area to - use. The ACE_CREATE flag will cause it to be created if it - doesn't already exist. The SHM_KEY value (from shmem.h) - uniquely identifies the segment and allows other apps to - attach to the same segment. Execute 'ipcs -m' before and - after starting this app to see that the segment is created. - (I can't for the life of me correlate the SHM_KEY value back - to the key/id reported by ipcs though.) - */ - ACE_Shared_Memory_SV shm_server (SHM_KEY, SHMSZ, - ACE_Shared_Memory_SV::ACE_CREATE); - - /* - The constructor created the segment for us but we still need - to map the segment into our address space. (Note that you - can pass a value to malloc() but it will be silently - igored.) The void* (cast to char*) that is returned will - point to the beginning of the shared segment. - */ - char *shm = (char *) shm_server.malloc (); - - /* - Since we're asking to create the segment, we will fail if it - already exists. We could fall back and simply attach to it - like the client but I'd rather not assume it was a previous - instance of this app that left the segment around. - */ - if( ! shm ) - { - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n\t(%P|%t) Cannot create shared memory segment.\n" - "\tUse 'ipcs' to see if it already exists\n", - argv[0]),100); - } - - /* - This second pointer will be used to walk through the block - of memory... - */ - char *s = shm; - - /* - Out of curiosity, I added this output message. The tests - I've done so far show me the same address for client and - server. What does your OS tell you? - */ - ACE_DEBUG ((LM_INFO, "(%P|%t) Shared Memory is at 0x%x\n", - shm )); - - /* - At this point, our application can use the pointer just like - any other given to us by new or malloc. For our purposes, - we'll copy in the alpabet as a null-terminated string. - */ - for (char c = 'a'; c <= 'z'; c++) - *s++ = c; - - *s = '\0'; - - /* - Using a simple not-too-busy loop, we'll wait for the client - (or anyone else) to change the first byte in the shared area - to a '*' character. This is where you would rather use - semaphores or some similar "resource light" approach. - */ - while (*shm != '*') - ACE_OS::sleep (1); - - /* - Let's see what the client did to the segment... - */ - for (char *s = shm; *s != '\0'; s++) - { - putchar (*s); - } - putchar ('\n'); - - /* - If you're done with the segment and ready for it to be - removed from the system, use the remove() method. Once the - program exits, do 'ipcs -m' again and you'll see that the - segment is gone. If you just want to terminate your use of - the segment but leave it around for other apps, use the - close() method instead. - - The free() method may be tempting but it doesn't actually do - anything. If your app is *really* done with the shared - memory then use either close() or remove(). - */ - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "%p\n", "remove")); - - return 0; -} - -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/019/server2.cpp b/docs/tutorials/019/server2.cpp deleted file mode 100644 index 00ab5de0152..00000000000 --- a/docs/tutorials/019/server2.cpp +++ /dev/null @@ -1,62 +0,0 @@ - -// $Id$ - -#include "shmem.h" - -#if defined(ACE_LACKS_SYSV_SHMEM) -int main (int, char *[]) -{ - ACE_ERROR_RETURN ((LM_ERROR, "System V Shared Memory not available on this platform\n"),100); -} -#else // ACE_LACKS_SYSV_SHMEM -int main (int, char *argv[]) -{ - // Be sure the segment is sized to hold our object. - ACE_Shared_Memory_SV shm_server (SHM_KEY, sizeof(SharedData), - ACE_Shared_Memory_SV::ACE_CREATE); - - char *shm = (char *) shm_server.malloc (); - - if( ! shm ) - { - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n\t(%P|%t) Cannot create shared memory segment.\n" - "\tUse 'ipcs' to see if it already exists\n", - argv[0]),100); - } - - ACE_DEBUG ((LM_INFO, "(%P|%t) Shared Memory is at 0x%x\n", - shm )); - - /* - Use the placement new syntax to stuff the object into the - correct location. I think they generally reserve this for - the advanced class... - */ - SharedData * sd = new(shm) SharedData; - - // Use the set() method to put some data into the object - sd->set(); - - // Set the 'available' flag to zero so that we can wait on it - sd->available(0); - - /* - Another cheesy busy loop while we wait for the object to - become available. The cool way would be to hide a semaphore - or two behind this method call & eliminate the sleep. - */ - while ( ! sd->available() ) - ACE_OS::sleep (1); - - // Show the user what's in the segment - sd->show(); - - // All done. - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "%p\n", "remove")); - - return 0; -} - -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/019/shmem.cpp b/docs/tutorials/019/shmem.cpp deleted file mode 100644 index d8f192daf0f..00000000000 --- a/docs/tutorials/019/shmem.cpp +++ /dev/null @@ -1,49 +0,0 @@ - -// $Id$ - -#include "shmem.h" - -#if ! defined(ACE_LACKS_SYSV_SHMEM) -/* - Set the available_ flag to zero & optionally initialize the buf_ - area. -*/ -SharedData::SharedData(int _initialize) - : available_(0) -{ - if( _initialize ) - { - ACE_OS::sprintf(buf_,"UNSET\n"); - } -} - -/* - Write the process ID into the buffer. This will prove to us that - the data really is shared between the client and server. -*/ -void SharedData::set(void) -{ - ACE_OS::sprintf(buf_,"My PID is (%d)\n",ACE_OS::getpid()); -} - -/* - Display the buffer to the user -*/ -void SharedData::show(void) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t) Shared Data text is (%s)\n", - buf_ )); -} - -// Show flag -int SharedData::available(void) -{ - return available_; -} - -// Set flag -void SharedData::available(int _available) -{ - available_ = _available; -} -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/019/shmem.h b/docs/tutorials/019/shmem.h deleted file mode 100644 index ca611782f88..00000000000 --- a/docs/tutorials/019/shmem.h +++ /dev/null @@ -1,43 +0,0 @@ - -// $Id$ - -#ifndef SHMEM_H -#define SHMEM_H - -// This is where you'll find the ACE_Shared_Memory_SV object -#include "ace/Shared_Memory_SV.h" - -// SHMSZ is just enough for the alphabet and a null terminator -#define SHMSZ 27 - -// Play with this, pick a value you like that isn't used by something else. -#define SHM_KEY 4200 - -/* - This is what we stuff into shared memory via placement new in the - second client/server pair. Notice that it is a very basic object - with no virtual methods and only concrete data. - */ -class SharedData -{ -public: - // Construct the object and optionally initialize buf_. - SharedData(int _initialize = 1); - - // Put some data into buf_ - void set(void); - // Show the data in buf_ - void show(void); - // What is the value of available_ - int available(void); - // Set the value of available_ - void available(int _available); - -protected: - // Big enough for a simple message - char buf_[128]; - // A cheap mutex - int available_; -}; - -#endif // SHMEM_H diff --git a/docs/tutorials/020/020-client.dsp b/docs/tutorials/020/020-client.dsp deleted file mode 100644 index 92d8ebe78b0..00000000000 --- a/docs/tutorials/020/020-client.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="020 client" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=020 client - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "020 client.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "020 client.mak" CFG="020 client - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "020 client - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "020 client - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "020 client - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "020 client - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "020 client - Win32 Release"
-# Name "020 client - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\client.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\mmap.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mmap.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/020/020-client2.dsp b/docs/tutorials/020/020-client2.dsp deleted file mode 100644 index 4bd463b95b3..00000000000 --- a/docs/tutorials/020/020-client2.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="020 client2" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=020 client2 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "020 client2.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "020 client2.mak" CFG="020 client2 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "020 client2 - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "020 client2 - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "020 client2 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "020 client2 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "020 client2 - Win32 Release"
-# Name "020 client2 - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mmap.h
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\client2.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\mmap.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/020/020-server.dsp b/docs/tutorials/020/020-server.dsp deleted file mode 100644 index 26eced19e76..00000000000 --- a/docs/tutorials/020/020-server.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="020 server" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=020 server - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "020 server.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "020 server.mak" CFG="020 server - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "020 server - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "020 server - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "020 server - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "020 server - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "020 server - Win32 Release"
-# Name "020 server - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mmap.h
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mmap.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/020/020-server2.dsp b/docs/tutorials/020/020-server2.dsp deleted file mode 100644 index 9011a553e0f..00000000000 --- a/docs/tutorials/020/020-server2.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="020 server2" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=020 server2 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "020 server2.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "020 server2.mak" CFG="020 server2 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "020 server2 - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "020 server2 - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "020 server2 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "020 server2 - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "020 server2 - Win32 Release"
-# Name "020 server2 - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mmap.h
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mmap.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\server2.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/020/Makefile b/docs/tutorials/020/Makefile deleted file mode 100644 index a7b0d9fca2a..00000000000 --- a/docs/tutorials/020/Makefile +++ /dev/null @@ -1,76 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client server client2 server2 - -FILES = mmap - -BUILD = $(VBIN) - -BSRC = $(addsuffix .cpp,$(BIN)) - -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : # - $(MAKE) SRC="$(SRC) $(BSRC)" depend - perl ../fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre *.pst > combine.shar && rm -f hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/020/client.cpp b/docs/tutorials/020/client.cpp deleted file mode 100644 index 6be12920164..00000000000 --- a/docs/tutorials/020/client.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -// $Id$ - -#include "mmap.h" - -int main (int, char *[]) -{ - ACE_Shared_Memory_MM shm_client (SHM_KEY, SHMSZ); - char *shm = (char *) shm_client.malloc (); - - ACE_DEBUG ((LM_INFO, "(%P|%t) Memory Mapped file is at 0x%x\n", - shm )); - - if( ! shm ) - { - ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) Could not get the mmapped file!\n"),100); - } - - for (char *s = shm; *s != '\0'; s++) - { - putchar (*s); - *s = toupper(*s); - } - - putchar ('\n'); - *shm = '*'; - - shm_client.close(); - - return 0; -} diff --git a/docs/tutorials/020/client2.cpp b/docs/tutorials/020/client2.cpp deleted file mode 100644 index 35ddc8ffe43..00000000000 --- a/docs/tutorials/020/client2.cpp +++ /dev/null @@ -1,25 +0,0 @@ - -// $Id$ - -#include "mmap.h" - -int main (int, char *[]) -{ - ACE_Shared_Memory_MM shm_client (SHM_KEY, sizeof(SharedData)); - - char *shm = (char *) shm_client.malloc (); - - ACE_DEBUG ((LM_INFO, "(%P|%t) Memory Mapped file is at 0x%x\n", - shm )); - - SharedData * sd = new(shm) SharedData(0); - - sd->show(); - sd->set(); - sd->available(1); - - shm_client.close(); - - return 0; -} - diff --git a/docs/tutorials/020/combine.shar b/docs/tutorials/020/combine.shar deleted file mode 100644 index 187ff0fadcb..00000000000 --- a/docs/tutorials/020/combine.shar +++ /dev/null @@ -1,343 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1998-12-28 18:00 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/020'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 426 -rw-rw-r-- hdr -# 69 -rw-rw-r-- bodies -# 509 -rw-rw-r-- page01.pre -# 524 -rw-rw-r-- page02.pre -# 115 -rw-rw-r-- page03.pre -# 411 -rw-rw-r-- page04.pre -# 102 -rw-rw-r-- page05.pre -# 371 -rw-rw-r-- page06.pre -# 132 -rw-rw-r-- page02.pst -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh07707; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 020</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 020</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Sharing your Memories with persistence</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1228173698 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -edd6dc67f13434391cf73b7604485b80 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 426 -eq "$shar_count" || - $echo 'hdr:' 'original size' '426,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -server.cpp -client.cpp -server2.cpp client2.cpp -mmap.h mmap.cpp -SHAR_EOF - $shar_touch -am 1228174898 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -a5d087bf1c11cf431c082ba146f3c6aa bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 69 -eq "$shar_count" || - $echo 'bodies:' 'original size' '69,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X This tutorial mirrors the previous. Instead of using shared memory, -X this time we'll be using a memory-mapped file. -X <p> -X The cool thing about doing it this way is that we gain -X persistence of memory even across reboots. I wonder if you -X could memory map a file that's mounted via NFS? -X <p> -X Like the shared memory tutorial, this one is also very basic and -X primitive. I'm assuming you've read that one, so I'll just hit -X the high points this time through.. -SHAR_EOF - $shar_touch -am 1228173898 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -333a5e5f8be0a5b8dc66424a50e5b4bd page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 509 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '509,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -X Here's our new server using a memory mapped file instead of Unix -X System V shared memory. Print out both servers and hold 'em up -X to a strong light. I think you'll see there isn't much -X difference. -X <p> -X The filename is defined in mmap.h as <i>mmapfile</i>. You can -X <i>cat</i> it any time to see what's in there. If you're -X feeling brave, try writting some data into it. On my system it -X causes unpleasant things to happen. I'd recommend that you -X don't do that! -<hr> -SHAR_EOF - $shar_touch -am 1228174498 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -94e75b2122d4d4c57e6f2f75c8d09b18 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 524 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '524,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -There's no important difference between this and the SV client. Is -X everybody thinking "template" here? -<hr> -SHAR_EOF - $shar_touch -am 1228174598 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -4ecbc37dd434a7f7ac6d17967625cfcb page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 115 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '115,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -I wanted to show placement new again & prove that you can use it with -X a memory mapped file just as easily as with a shared memory -X segment. -X <p> -Imagine if you had an object that contained an image & then you mapped -X that to a file... Instead of a bunch of jpg files laying -X around, you would actually have objects instead. Save the -X image? No problem, it's already there! -<hr> -SHAR_EOF - $shar_touch -am 1228175398 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -22e02b4170bdf5e6cd8894b8983c737a page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 411 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '411,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -The mmap.h where we define stuff that needs to be shared between the -X apps at compile-time. -<hr> -SHAR_EOF - $shar_touch -am 1228175198 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -4dd4610ed79583de6edd62eeb02bf7fe page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 102 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '102,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -This one was even shorter than the last! -X -X <ul> -X <li><A HREF="server.cpp">server.cpp</A> -X <li><A HREF="client.cpp">client.cpp</A> -X <li><A HREF="server2.cpp">server2.cpp</A> -X <li><A HREF="client2.cpp">client2.cpp</A> -X <li><A HREF="mmap.h">mmap.h</A> -X <li><A HREF="mmap.cpp">mmap.cpp</A> -X <li><A HREF="Makefile">Makefile</A> -X </ul> -SHAR_EOF - $shar_touch -am 1228175498 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pre:' 'MD5 check failed' -8c515447a6b2a9c39a25915248260602 page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 371 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '371,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pst ============== -if test -f 'page02.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pst' '(file already exists)' -else - $echo 'x -' extracting 'page02.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pst' && -<HR> -BTW: In ACE 4.6.7 and prior there is a bug that prevents the remove() -X method from actually removing the physical file. -SHAR_EOF - $shar_touch -am 1228175398 'page02.pst' && - chmod 0664 'page02.pst' || - $echo 'restore of' 'page02.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pst:' 'MD5 check failed' -10ea86cd7f1b8484868846bd8761e582 page02.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`" - test 132 -eq "$shar_count" || - $echo 'page02.pst:' 'original size' '132,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh07707 -exit 0 diff --git a/docs/tutorials/020/mmap.cpp b/docs/tutorials/020/mmap.cpp deleted file mode 100644 index 6ee9f1198c8..00000000000 --- a/docs/tutorials/020/mmap.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -// $Id$ - -#include "mmap.h" - -SharedData::SharedData(int _initialize) - : available_(0) -{ - if( _initialize ) - { - ACE_OS::sprintf(buf_,"UNSET\n"); - } -} - -void SharedData::set(void) -{ - ACE_OS::sprintf(buf_,"My PID is (%d)\n",ACE_OS::getpid()); -} - -void SharedData::show(void) -{ - ACE_DEBUG ((LM_INFO, "(%P|%t) Shared Data text is (%s)\n", - buf_ )); -} - -int SharedData::available(void) -{ - return available_; -} - -void SharedData::available(int _available) -{ - available_ = _available; -} diff --git a/docs/tutorials/020/mmap.h b/docs/tutorials/020/mmap.h deleted file mode 100644 index 5c3d8bce778..00000000000 --- a/docs/tutorials/020/mmap.h +++ /dev/null @@ -1,39 +0,0 @@ - -// $Id$ - -#ifndef MMAP_H -#define MMAP_H - -// The expected filename for ACE_Shared_Memory_MM.h -#include "ace/Shared_Memory_MM.h" - -// Just enough for the alphabet... -#define SHMSZ 27 - -/* - Here we use a real filename instead of an arbitrary number. This - actually will exist in the filesystem. You can 'cat' it and - everything! -*/ -#define SHM_KEY "mmapfile" - -/* - The SV Shared Memory SharedData object returns. It is identical to - the one we used in that tutorial. I didn't even change the name. - */ -class SharedData -{ -public: - SharedData(int _initialize = 1); - - void set(void); - void show(void); - int available(void); - void available(int _available); - -protected: - char buf_[128]; - int available_; -}; - -#endif // MMAP_H diff --git a/docs/tutorials/020/mmapfile b/docs/tutorials/020/mmapfile deleted file mode 100644 index 7ea5caf832b..00000000000 --- a/docs/tutorials/020/mmapfile +++ /dev/null @@ -1,8 +0,0 @@ -root tty2 Dec 13 19:43 -jcej tty5 Dec 14 20:36 -dialout modem Dec 28 15:51 (/usr/sbin/diald -daemon -f /etc/diald.lads) -jcej ttyp1 Dec 22 00:31 (:0.0) -jcej ttyp2 Dec 22 11:22 (:0.0) -jcej ttyp7 Dec 22 18:22 (:0.0) -jcej ttyp9 Dec 24 00:04 (:0.0) -jcej ttyp8 Dec 22 18:47 (:0.0) diff --git a/docs/tutorials/020/page01.html b/docs/tutorials/020/page01.html deleted file mode 100644 index 9b88f442c08..00000000000 --- a/docs/tutorials/020/page01.html +++ /dev/null @@ -1,26 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 020</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 020</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories with persistence</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - This tutorial mirrors the previous. Instead of using shared memory, - this time we'll be using a memory-mapped file. - <p> - The cool thing about doing it this way is that we gain - persistence of memory even across reboots. I wonder if you - could memory map a file that's mounted via NFS? - <p> - Like the shared memory tutorial, this one is also very basic and - primitive. I'm assuming you've read that one, so I'll just hit - the high points this time through.. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/020/page02.html b/docs/tutorials/020/page02.html deleted file mode 100644 index dc5f293b16a..00000000000 --- a/docs/tutorials/020/page02.html +++ /dev/null @@ -1,71 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 020</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 020</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories with persistence</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - Here's our new server using a memory mapped file instead of Unix - System V shared memory. Print out both servers and hold 'em up - to a strong light. I think you'll see there isn't much - difference. - <p> - The filename is defined in mmap.h as <i>mmapfile</i>. You can - <i>cat</i> it any time to see what's in there. If you're - feeling brave, try writting some data into it. On my system it - causes unpleasant things to happen. I'd recommend that you - don't do that! -<hr> -<PRE> - -<font color=blue>#include</font> "<font color=green>mmap.h</font>" - -int -main (int, char *[]) -{ - <font color=red>/* - The default behavior of the memory map wrapper is to create - the file if it doesn't exist. This is a minor change from - the SV shared memory wrapper. - */</font> - ACE_Shared_Memory_MM shm_server (SHM_KEY, SHMSZ); - char *shm = (char *) shm_server.malloc (); - char *s = shm; - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Memory Mapped file is at 0x%x\n</font>", - shm )); - - for (char c = 'a'; c <= 'z'; c++) - *s++ = c; - - *s = '\0'; - - while (*shm != '*') - <font color=#008888>ACE_OS::sleep</font> (1); - - for (char *s = shm; *s != '\0'; s++) - { - putchar (*s); - } - - putchar ('\n'); - - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>remove</font>")); - - return 0; -} - -</PRE> -<HR> -BTW: In ACE 4.6.7 and prior there is a bug that prevents the remove() - method from actually removing the physical file. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/020/page03.html b/docs/tutorials/020/page03.html deleted file mode 100644 index d7b41c8e51e..00000000000 --- a/docs/tutorials/020/page03.html +++ /dev/null @@ -1,51 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 020</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 020</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories with persistence</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -There's no important difference between this and the SV client. Is - everybody thinking "template" here? -<hr> -<PRE> - -<font color=blue>#include</font> "<font color=green>mmap.h</font>" - -int main (int, char *[]) -{ - ACE_Shared_Memory_MM shm_client (SHM_KEY, SHMSZ); - char *shm = (char *) shm_client.malloc (); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Memory Mapped file is at 0x%x\n</font>", - shm )); - - if( ! shm ) - { - ACE_ERROR_RETURN ((LM_ERROR,"<font color=green>(%P|%t) Could not get the mmapped file!\n</font>"),100); - } - - for (char *s = shm; *s != '\0'; s++) - { - putchar (*s); - *s = toupper(*s); - } - - putchar ('\n'); - *shm = '*'; - - shm_client.close(); - - return 0; -} - -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/020/page04.html b/docs/tutorials/020/page04.html deleted file mode 100644 index 037b820b63e..00000000000 --- a/docs/tutorials/020/page04.html +++ /dev/null @@ -1,83 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 020</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 020</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories with persistence</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -I wanted to show placement new again & prove that you can use it with - a memory mapped file just as easily as with a shared memory - segment. - <p> -Imagine if you had an object that contained an image & then you mapped - that to a file... Instead of a bunch of jpg files laying - around, you would actually have objects instead. Save the - image? No problem, it's already there! -<hr> -<HR width=50%><P><center>server2.cpp</center><HR width=50%> -<PRE> - -<font color=blue>#include</font> "<font color=green>mmap.h</font>" - -int -main (int, char *[]) -{ - ACE_Shared_Memory_MM shm_server (SHM_KEY, sizeof(SharedData) ); - - char *shm = (char *) shm_server.malloc (); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Memory Mapped file is at 0x%x\n</font>", - shm )); - - SharedData * sd = new(shm) SharedData; - - sd->set(); - sd->available(0); - - while ( ! sd->available() ) - <font color=#008888>ACE_OS::sleep</font> (1); - - sd->show(); - - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>remove</font>")); - - return 0; -} - -</PRE> -<HR width=50%><P><center>client2.cpp</center><HR width=50%> -<PRE> - -<font color=blue>#include</font> "<font color=green>mmap.h</font>" - -int main (int, char *[]) -{ - ACE_Shared_Memory_MM shm_client (SHM_KEY, sizeof(SharedData)); - - char *shm = (char *) shm_client.malloc (); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Memory Mapped file is at 0x%x\n</font>", - shm )); - - SharedData * sd = new(shm) SharedData(0); - - sd->show(); - sd->set(); - sd->available(1); - - shm_client.close(); - - return 0; -} - -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/020/page05.html b/docs/tutorials/020/page05.html deleted file mode 100644 index 04016a34532..00000000000 --- a/docs/tutorials/020/page05.html +++ /dev/null @@ -1,94 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 020</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 020</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories with persistence</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The mmap.h where we define stuff that needs to be shared between the - apps at compile-time. -<hr> -<HR width=50%><P><center>mmap.h</center><HR width=50%> -<PRE> - -<font color=blue>#ifndef</font> <font color=purple>MMAP_H</font> -<font color=blue>#define</font> <font color=purple>MMAP_H</font> - -<font color=red>// The expected filename for ACE_Shared_Memory_MM.h</font> -<font color=blue>#include</font> "<font color=green>ace/Shared_Memory_MM.h</font>" - -<font color=red>// Just enough for the alphabet...</font> -<font color=blue>#define</font> <font color=purple>SHMSZ</font> 27 - -<font color=red>/* - Here we use a real filename instead of an arbitrary number. This - actually will exist in the filesystem. You can 'cat' it and - everything! -*/</font> -<font color=blue>#define</font> <font color=purple>SHM_KEY</font> "<font color=green>mmapfile</font>" - -<font color=red>/* - The SV Shared Memory SharedData object returns. It is identical to - the one we used in that tutorial. I didn't even change the name. - */</font> -class SharedData -{ -public: - SharedData(int _initialize = 1); - - void set(void); - void show(void); - int available(void); - void available(int _available); - -protected: - char buf_[128]; - int available_; -}; - -<font color=blue>#endif</font> <font color=red>// MMAP_H</font> -</PRE> -<HR width=50%><P><center>mmap.cpp</center><HR width=50%> -<PRE> - -<font color=blue>#include</font> "<font color=green>mmap.h</font>" - -<font color=#008888>SharedData::SharedData</font>(int _initialize) - : available_(0) -{ - if( _initialize ) - { - <font color=#008888>ACE_OS::sprintf</font>(buf_,"<font color=green>UNSET\n</font>"); - } -} - -void <font color=#008888>SharedData::set</font>(void) -{ - <font color=#008888>ACE_OS::sprintf</font>(buf_,"<font color=green>My PID is (%d)\n</font>",ACE_OS::getpid()); -} - -void <font color=#008888>SharedData::show</font>(void) -{ - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Data text is (%s)\n</font>", - buf_ )); -} - -int <font color=#008888>SharedData::available</font>(void) -{ - return available_; -} - -void <font color=#008888>SharedData::available</font>(int _available) -{ - available_ = _available; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/020/page06.html b/docs/tutorials/020/page06.html deleted file mode 100644 index af67e7754d6..00000000000 --- a/docs/tutorials/020/page06.html +++ /dev/null @@ -1,27 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 020</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 020</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Sharing your Memories with persistence</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -This one was even shorter than the last! - - <ul> - <li><A HREF="server.cpp">server.cpp</A> - <li><A HREF="client.cpp">client.cpp</A> - <li><A HREF="server2.cpp">server2.cpp</A> - <li><A HREF="client2.cpp">client2.cpp</A> - <li><A HREF="mmap.h">mmap.h</A> - <li><A HREF="mmap.cpp">mmap.cpp</A> - <li><A HREF="Makefile">Makefile</A> - </ul> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/020/server.cpp b/docs/tutorials/020/server.cpp deleted file mode 100644 index 34cab1d8637..00000000000 --- a/docs/tutorials/020/server.cpp +++ /dev/null @@ -1,41 +0,0 @@ - -// $Id$ - -#include "mmap.h" - -int -main (int, char *[]) -{ - /* - The default behavior of the memory map wrapper is to create - the file if it doesn't exist. This is a minor change from - the SV shared memory wrapper. - */ - ACE_Shared_Memory_MM shm_server (SHM_KEY, SHMSZ); - char *shm = (char *) shm_server.malloc (); - char *s = shm; - - ACE_DEBUG ((LM_INFO, "(%P|%t) Memory Mapped file is at 0x%x\n", - shm )); - - for (char c = 'a'; c <= 'z'; c++) - *s++ = c; - - *s = '\0'; - - while (*shm != '*') - ACE_OS::sleep (1); - - for (s = shm; *s != '\0'; s++) - { - putchar (*s); - } - - putchar ('\n'); - - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "%p\n", "remove")); - - return 0; -} - diff --git a/docs/tutorials/020/server2.cpp b/docs/tutorials/020/server2.cpp deleted file mode 100644 index 9b5e6b21fee..00000000000 --- a/docs/tutorials/020/server2.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -// $Id$ - -#include "mmap.h" - -int -main (int, char *[]) -{ - ACE_Shared_Memory_MM shm_server (SHM_KEY, sizeof(SharedData) ); - - char *shm = (char *) shm_server.malloc (); - - ACE_DEBUG ((LM_INFO, "(%P|%t) Memory Mapped file is at 0x%x\n", - shm )); - - SharedData * sd = new(shm) SharedData; - - sd->set(); - sd->available(0); - - while ( ! sd->available() ) - ACE_OS::sleep (1); - - sd->show(); - - if (shm_server.remove () < 0) - ACE_ERROR ((LM_ERROR, "%p\n", "remove")); - - return 0; -} - diff --git a/docs/tutorials/021/021-client.dsp b/docs/tutorials/021/021-client.dsp deleted file mode 100644 index 052ba50237a..00000000000 --- a/docs/tutorials/021/021-client.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="021 client" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=021 client - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "021 client.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "021 client.mak" CFG="021 client - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "021 client - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "021 client - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "021 client - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "021 client - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "021 client - Win32 Release"
-# Name "021 client - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\client.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\mpool.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mpool.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/021/021-server.dsp b/docs/tutorials/021/021-server.dsp deleted file mode 100644 index 3667e52aa5f..00000000000 --- a/docs/tutorials/021/021-server.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="021 server" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=021 server - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "021 server.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "021 server.mak" CFG="021 server - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "021 server - Win32 Release" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE "021 server - Win32 Debug" (based on\
- "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "021 server - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "021 server - 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 "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "021 server - Win32 Release"
-# Name "021 server - Win32 Debug"
-# Begin Group "Header Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mpool.h
-# End Source File
-# End Group
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\mpool.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/021/Makefile b/docs/tutorials/021/Makefile deleted file mode 100644 index 846ca3fcf8c..00000000000 --- a/docs/tutorials/021/Makefile +++ /dev/null @@ -1,76 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client server - -FILES = mpool - -BUILD = $(VBIN) - -BSRC = $(addsuffix .cpp,$(BIN)) - -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : # - $(MAKE) SRC="$(SRC) $(BSRC)" depend - perl ../fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre > combine.shar && rm -f hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/021/client.cpp b/docs/tutorials/021/client.cpp deleted file mode 100644 index b53b5ed637e..00000000000 --- a/docs/tutorials/021/client.cpp +++ /dev/null @@ -1,116 +0,0 @@ - -// $Id$ - -#include "mpool.h" - -#if defined(ACE_LACKS_SYSV_SHMEM) -int main (int, char *[]) -{ - ACE_ERROR_RETURN ((LM_ERROR, "System V Semaphores not available on this platform.\n"),100); -} -#else // ACE_LACKS_SYSV_SHMEM -int main (int, char *[]) -{ - /* - Use the same pool name used by the server when we create our - Allocator. This assures us that we don't create a whole new - pool. - */ - Allocator allocator(Constants::PoolName); - - /* - You can put anything in the memory pool. Not just the - character array we want. The find() method till, therefore, - return a void* that we will have to cast. - */ - void * region; - - /* - We use find() to locate a named region in the pool. This is - the counterpart to bind() used in the server. - Here, we go try to find the region that the server has created - and filled with data. If there was a problem getting the pool - or finding the region, we'll get back -1 from find(). - */ - if( allocator.pool().find(Constants::RegionName,region) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "Cannot find the name '%s'\n", - Constants::RegionName), 100 ); - } - - /* - Since find() returns us a void*, we cast it here to the char* - that we want. - */ - char *shm = (char *)region; - - ACE_DEBUG ((LM_INFO, "Shared memory is at 0x%x\n", shm )); - - /* - The same pair of semaphores as used by the server are created - here. We probably don't need the CREATE flag since the server - should have already done that. There may be some very small - windows, however, where the server would have created the - memory pool but not yet gotten to the semaphores. - */ - ACE_SV_Semaphore_Complex mutex; - ACE_ASSERT (mutex.open (Constants::SEM_KEY_1, - ACE_SV_Semaphore_Complex::ACE_CREATE, 0) != -1); - - ACE_SV_Semaphore_Complex synch; - ACE_ASSERT (synch.open (Constants::SEM_KEY_2, - ACE_SV_Semaphore_Complex::ACE_CREATE, 0) != -1); - - /* - It doesn't matter if we created 'mutex' or if the server did. - In either case, it was created in a locked state and we will - block here until somebody unlocks it. In our scenario, that - will have to be the server. - */ - if (mutex.acquire () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P) client mutex.acquire"), 1); - } - - /* - Now that we know it is safe to access the data, we'll run - through and make sure that it contains what we think the server - supplied. - */ - for (int i = 0; i < Constants::SHMSZ; i++) - { - ACE_ASSERT (Constants::SHMDATA[i] == shm[i]); - } - - /* - Look back at the server. After filling the region, it will - attempt to acquire the lock on 'synch'. It will wait there - until we release() the semaphore. That will allow it to remove - the pool and cleanup. We can simply exit once we perform the - release. (Ok, a free() of the region would probably be polite...) - */ - if (synch.release () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "(%P) client synch.release"), 1); - } - - return 0; -} - -/* - Again, we have the necessary explicit template instantiations - because I based this on an ACE example instead of creating it from scratch. - */ -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple>; -template class ACE_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Write_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Read_Guard<ACE_SV_Semaphore_Simple>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple> -#pragma instantiate ACE_Guard<ACE_SV_Semaphore_Simple> -#pragma instantiate ACE_Write_Guard<ACE_SV_Semaphore_Simple> -#pragma instantiate ACE_Read_Guard<ACE_SV_Semaphore_Simple> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/021/combine.shar b/docs/tutorials/021/combine.shar deleted file mode 100644 index 5b92de500be..00000000000 --- a/docs/tutorials/021/combine.shar +++ /dev/null @@ -1,329 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1999-01-06 14:26 EST by <jcej@caldera.lads.com>. -# Source directory was `/scsiA/home/jcej/projects/ACE_wrappers/docs/tutorials/021'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 409 -rw-rw-r-- hdr -# 47 -rw-rw-r-- bodies -# 562 -rw-rw-r-- page01.pre -# 281 -rw-rw-r-- page02.pre -# 201 -rw-rw-r-- page03.pre -# 287 -rw-rw-r-- page04.pre -# 287 -rw-rw-r-- page05.pre -# 604 -rw-rw-r-- page06.pre -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh07125; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <TITLE>ACE Tutorial 021</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 0103180599 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -9ffa6eb1308f4872f390b30f74a6de3b hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 409 -eq "$shar_count" || - $echo 'hdr:' 'original size' '409,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -server.cpp -client.cpp -mpool.h -mpool.cpp -SHAR_EOF - $shar_touch -am 0106135399 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -470abefc6e5e401ad9ffdfa76e3ca143 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 47 -eq "$shar_count" || - $echo 'bodies:' 'original size' '47,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X The previous two tutorials were very primitive & basic. They -X showed very simple uses of shared memory and memory mapped -X files. -X <p> -X If we move the level of abstraction up just a bit, the next -X thing we encounter is memory pools. ACE_Malloc<> provides -X this to us. -X <p> -X In this tutorial, we'll use ACE_Malloc<> to create a -X memory pool that is sharable between a client and server. We'll -X use a memory mapped file to provide the physical storage but -X shared memory works just as well. -SHAR_EOF - $shar_touch -am 0103180499 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -83956a1b05e5f8823afbdb8a84d8ac11 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 562 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '562,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -X The key components for creating the memory pool are: -X <ul> -X <li>Create and name the pool -X <li>Allocate a chunk (region) of memory from the pool -X <li>Name the allocated region -X </ul> -X The rest of it is just critical sections and data manipulation. -<hr> -SHAR_EOF - $shar_touch -am 0103180899 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -1bde237d2082c2f88f4802965e0b393d page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 281 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '281,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -X The client side is a little simpler than the server. Mainly -X because we don't try to delete the pool: -X <ul> -X <li>Create an Allocator to access the pool -X <li>Find the named region -X </ul> -<hr> -SHAR_EOF - $shar_touch -am 0106135499 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -bd3bbfe6dbece827f8259d394d89ff58 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 201 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '201,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -X Everything common the server & client is kept here. In -X particular, the Constants class where we keep the names & -X semaphore keys. -X <p> -X The Allocator class is just a thin wrapper around -X ACE_Malloc<> that moves some of the details out of the -X application logic. -<hr> -SHAR_EOF - $shar_touch -am 0106135699 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -a95d570fb8b7aca15802d9abdba84b81 page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 287 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '287,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -X Everything common the server & client is kept here. In -X particular, the Constants class where we keep the names & -X semaphore keys. -X <p> -X The Allocator class is just a thin wrapper around -X ACE_Malloc<> that moves some of the details out of the -X application logic. -<hr> -SHAR_EOF - $shar_touch -am 0106140399 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -a95d570fb8b7aca15802d9abdba84b81 page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 287 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '287,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -X As you can see, using a memory pool is really rather easy. The -X most difficult part, as always, is with the synch mechanisms. -X <P> -X The other nice thing about ACE_Malloc<> is that you can swap -X between System V shared memory and memory mapped files just by -X changing the template parameters. The truly adventurous will -X likely find a runtime way of doing this. -X <p> -X -X <ul> -X <li><A HREF="Makefile">Makefile</A> -X <li><A HREF="server.cpp">server.cpp</A> -X <li><A HREF="client.cpp">client.cpp</A> -X <li><A HREF="mpool.h">mpool.h</A> -X <li><A HREF="mpool.cpp">mpool.cpp</A> -X </ul> -SHAR_EOF - $shar_touch -am 0106142499 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page06.pre:' 'MD5 check failed' -68fa5365d4add68561720a1f24bb980f page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 604 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '604,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh07125 -exit 0 diff --git a/docs/tutorials/021/mpool.cpp b/docs/tutorials/021/mpool.cpp deleted file mode 100644 index 99c2cc9fc34..00000000000 --- a/docs/tutorials/021/mpool.cpp +++ /dev/null @@ -1,70 +0,0 @@ - -// $Id$ - -#include "mpool.h" - -#if ! defined(ACE_LACKS_SYSV_SHMEM) - -/* - Set the values of all of the constants. This guarantees that client - and server don't get confused. - */ -const int Constants::SEM_KEY_1 = ACE_DEFAULT_SEM_KEY + 1; -const int Constants::SEM_KEY_2 = ACE_DEFAULT_SEM_KEY + 2; - -const int Constants::SHMSZ = 27; -const char * Constants::SHMDATA = "abcdefghijklmnopqrstuvwxyz"; - -const char * Constants::PoolName = "SharedMemoryPool"; -const char * Constants::RegionName = "Alphabet"; - -/* - We have to create a copy of the _name parameter in case the caller - has dynamically allocated it. The pool_ is set to NULL & will be - allocated by the accessor. - */ -Allocator::Allocator( const char * _name ) - : name_(ACE_OS::strdup(_name)), - pool_(0) -{ - if( ! name_ ) - { - ACE_ERROR ((LM_ERROR, "(%P) %p", - "Allocator::Allocator cannot strdup pool name" )); - } -} - -Allocator::~Allocator(void) -{ - /* - strdup() uses malloc(), so we must use free() to clean up. - */ - if( name_ ) - { - free(name_); - } - - // delete doesn't really care if you give it a NULL pointer. - delete pool_; -} - -/* - Allocate the pool. Since we return a reference, we'll be in really - bad shape if the new fails. This is a great place to throw an - exception! - The other concern is thread safety. If two threads call here at - about the same time, we may create the pool twice. We can't use a - Singleton because we want to have multiple Allocator instances. The - Singleton techniques can be used though. - */ -Allocator::pool_t & Allocator::pool(void) -{ - if( ! pool_ ) - { - pool_ = new pool_t( name_ ); - } - - return *pool_; -} - -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/021/mpool.h b/docs/tutorials/021/mpool.h deleted file mode 100644 index 3199980a0f2..00000000000 --- a/docs/tutorials/021/mpool.h +++ /dev/null @@ -1,68 +0,0 @@ - -// $Id$ - -#ifndef MPOOL_H -#define MPOOL_H - -// Everything else we need is in this one header -#include "ace/Malloc.h" - - -#if ! defined(ACE_LACKS_SYSV_SHMEM) - -/* - With this we will abstract away some of the details of the memory - pool. Note that we don't treat this as a singleton because an - application may need more than one pool. Each would have a - different name and be used for different purposes. - */ -class Allocator -{ -public: - // The pool name will be used to create a unique semaphore to - // keep this pool separate from others. - Allocator( const char * _name = "MemoryPool" ); - ~Allocator(void); - - typedef ACE_Malloc<ACE_MMAP_Memory_Pool, ACE_SV_Semaphore_Simple> pool_t; - - // Provide an accessor to the pool. This will also allocate the - // pool when first invoked. - pool_t & pool(void); - -protected: - - // The name we gave to the pool - char * name_; - - pool_t * pool_; -}; - -/* - The client and server need to agree on a certain set of values. By - placing them in the Constants class we can eliminate a bit of confusion. - */ -class Constants -{ -public: - // The semaphore keys are needed for the two semaphores that - // synch access to the shared memory area. - static const int SEM_KEY_1; - static const int SEM_KEY_2; - - // How big the pool will be and what we'll put into it. A real - // app wouldn't need SHMDATA of course. - static const int SHMSZ; - static const char * SHMDATA; - - // The name assigned to the memory pool by the server is needed - // by the client. Without it, the pool cannot be found. - // Likewise, the name the server will bind() to the region of the - // pool must be available to the client. - static const char * PoolName; - static const char * RegionName; -}; - -#endif // ACE_LACKS_SYSV_SHMEM - -#endif // MPOOL_H diff --git a/docs/tutorials/021/page01.html b/docs/tutorials/021/page01.html deleted file mode 100644 index 262bdeac5cc..00000000000 --- a/docs/tutorials/021/page01.html +++ /dev/null @@ -1,28 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 021</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - The previous two tutorials were very primitive & basic. They - showed very simple uses of shared memory and memory mapped - files. - <p> - If we move the level of abstraction up just a bit, the next - thing we encounter is memory pools. ACE_Malloc<> provides - this to us. - <p> - In this tutorial, we'll use ACE_Malloc<> to create a - memory pool that is sharable between a client and server. We'll - use a memory mapped file to provide the physical storage but - shared memory works just as well. -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/021/page02.html b/docs/tutorials/021/page02.html deleted file mode 100644 index 0c1a4014b61..00000000000 --- a/docs/tutorials/021/page02.html +++ /dev/null @@ -1,172 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 021</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - The key components for creating the memory pool are: - <ul> - <li>Create and name the pool - <li>Allocate a chunk (region) of memory from the pool - <li>Name the allocated region - </ul> - The rest of it is just critical sections and data manipulation. -<hr><PRE> - -<font color=red>// $Id$</font> - -<font color=red>/* - I've hidden the details in an Allocator class declared in mpool.h - We'll come to that a little later. -*/</font> -<font color=blue>#include</font> "<font color=green>mpool.h</font>" - -int main (int, char *[]) -{ - <font color=red>/* - Construction of an Allocator will create the memory pool and - provide it with a name. The Constants class is also - declared in mpool.h to keep server and client on the same - page. The name is used to generate a unique semaphore which - prevents simultaneous access to the pools housekeeping - information. (Note that you still have to provide your own - synch mechanisms for the data *you* put in the pool.) - */</font> - Allocator allocator(<font color=#008888>Constants::PoolName</font>); - - <font color=red>/* - The Allocator class provides the pool() member so that you - have access to the actual memory pool. A more robust - implementation would behave more as a bridge class but this - is good enough for what we're doing here. - Once you have a reference to the pool, the malloc() method - can be used to get some bytes. If successful, shm will - point to the data. Otherwise, it will be zero. - */</font> - char *shm = (char *) allocator.pool().malloc (27); - - ACE_ASSERT( shm != 0 ); - - <font color=red>/// FYI</font> - ACE_DEBUG ((LM_INFO, "<font color=green>Shared memory is at 0x%x\n</font>", shm )); - - <font color=red>/* - Something that we can do with a memory pool is map a name to - a region provided by malloc. By doing this, we can - communicate that name to the client as a rendezvous - location. Again, a member of Constants is used to keep the - client and server coordinated. - */</font> - if( allocator.pool().bind(<font color=#008888>Constants::RegionName</font>,shm) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>Cannot bind the name '%s' to the pointer 0x%x\n</font>", - <font color=#008888>Constants::RegionName</font>,shm), 100 ); - } - - <font color=red>/* - One of the best ways to synch between different processes is - through the use of semaphores. ACE_SV_Semaphore_Complex - hides the gory details and lets us use them rather easily. - - Here, we'll create two semaphores: mutex and synch. mutex - will be used to provide mutually exclusive access to the - shared region for writting/reading. synch will be used to - prevent the server from removing the memory pool before the - client is done with it. - - Both semaphores are created in an initially locked state. - */</font> - - ACE_SV_Semaphore_Complex mutex; - ACE_ASSERT (mutex.open (<font color=#008888>Constants::SEM_KEY_1</font>, - <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1); - - ACE_SV_Semaphore_Complex synch; - ACE_ASSERT (synch.open (<font color=#008888>Constants::SEM_KEY_2</font>, - <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1); - - <font color=red>/* - We know the mutex is locked because we created it that way. - Take a moment to write some data into the shared region. - */</font> - for (int i = 0; i < <font color=#008888>Constants::SHMSZ</font>; i++) - { - shm[i] = <font color=#008888>Constants::SHMDATA</font>[i]; - } - - <font color=red>/* - The client will be blocking on an acquire() of mutex. By - releasing it here, the client can go look at the shared data. - */</font> - if (mutex.release () == -1) - { - ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p</font>", "<font color=green>server mutex.release</font>")); - } - <font color=red>/* - Even though we created the synch semaphore in a locked - state, if we attempt to acquire() it, we will block. Our - design requires that the client release() synch when it is - OK for us to remove the shared memory. - */</font> - else if (synch.acquire () == -1) - { - ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p</font>", "<font color=green>server synch.acquire</font>")); - } - - <font color=red>/* - This will remove all of the memory pool's resources. In the - case where a memory mapped file is used, the physical file - will also be removed. - */</font> - if (allocator.pool ().remove () == -1) - { - ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p\n</font>", "<font color=green>server allocator.remove</font>")); - } - - <font color=red>/* - We now have to cleanup the semaphores we created. Use the - ipcs command to see that they did, indeed, go away after the - server exits. - */</font> - - if (mutex.remove () == -1) - { - ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p\n</font>", "<font color=green>server mutex.remove</font>")); - } - - if (synch.remove () == -1) - { - ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p\n</font>", "<font color=green>server synch.remove</font>")); - } - - return 0; - -} - -<font color=red>/* - This tutorial was created by shamelessly modifying one of the ACE - examples. Someone there had already created the necessary explicit - template instantiations & I don't want them to go to waste... - */</font> -<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>) -template class ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple>; -template class ACE_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Write_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Read_Guard<ACE_SV_Semaphore_Simple>; -<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Guard<ACE_SV_Semaphore_Simple> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Write_Guard<ACE_SV_Semaphore_Simple> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Read_Guard<ACE_SV_Semaphore_Simple> -<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/021/page03.html b/docs/tutorials/021/page03.html deleted file mode 100644 index 017134a55e5..00000000000 --- a/docs/tutorials/021/page03.html +++ /dev/null @@ -1,132 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 021</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - The client side is a little simpler than the server. Mainly - because we don't try to delete the pool: - <ul> - <li>Create an Allocator to access the pool - <li>Find the named region - </ul> -<hr><PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>mpool.h</font>" - -int main (int, char *[]) -{ - <font color=red>/* - Use the same pool name used by the server when we create our - Allocator. This assures us that we don't create a whole new - pool. - */</font> - Allocator allocator(<font color=#008888>Constants::PoolName</font>); - - <font color=red>/* - You can put anything in the memory pool. Not just the - character array we want. The find() method till, therefore, - return a void* that we will have to cast. - */</font> - void * region; - - <font color=red>/* - We use find() to locate a named region in the pool. This is - the counterpart to bind() used in the server. - Here, we go try to find the region that the server has created - and filled with data. If there was a problem getting the pool - or finding the region, we'll get back -1 from find(). - */</font> - if( allocator.pool().find(<font color=#008888>Constants::RegionName</font>,region) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>Cannot find the name '%s'\n</font>", - <font color=#008888>Constants::RegionName</font>), 100 ); - } - - <font color=red>/* - Since find() returns us a void*, we cast it here to the char* - that we want. - */</font> - char *shm = (char *)region; - - ACE_DEBUG ((LM_INFO, "<font color=green>Shared memory is at 0x%x\n</font>", shm )); - - <font color=red>/* - The same pair of semaphores as used by the server are created - here. We probably don't need the CREATE flag since the server - should have already done that. There may be some very small - windows, however, where the server would have created the - memory pool but not yet gotten to the semaphores. - */</font> - ACE_SV_Semaphore_Complex mutex; - ACE_ASSERT (mutex.open (<font color=#008888>Constants::SEM_KEY_1</font>, - <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1); - - ACE_SV_Semaphore_Complex synch; - ACE_ASSERT (synch.open (<font color=#008888>Constants::SEM_KEY_2</font>, - <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1); - - <font color=red>/* - It doesn't matter if we created 'mutex' or if the server did. - In either case, it was created in a locked state and we will - block here until somebody unlocks it. In our scenario, that - will have to be the server. - */</font> - if (mutex.acquire () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P) client mutex.acquire</font>"), 1); - } - - <font color=red>/* - Now that we know it is safe to access the data, we'll run - through and make sure that it contains what we think the server - supplied. - */</font> - for (int i = 0; i < <font color=#008888>Constants::SHMSZ</font>; i++) - { - ACE_ASSERT (<font color=#008888>Constants::SHMDATA</font>[i] == shm[i]); - } - - <font color=red>/* - Look back at the server. After filling the region, it will - attempt to acquire the lock on 'synch'. It will wait there - until we release() the semaphore. That will allow it to remove - the pool and cleanup. We can simply exit once we perform the - release. (Ok, a free() of the region would probably be polite...) - */</font> - if (synch.release () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P) client synch.release</font>"), 1); - } - - return 0; -} - -<font color=red>/* - Again, we have the necessary explicit template instantiations - because I based this on an ACE example instead of creating it from scratch. - */</font> -<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>) -template class ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple>; -template class ACE_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Write_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Read_Guard<ACE_SV_Semaphore_Simple>; -<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Guard<ACE_SV_Semaphore_Simple> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Write_Guard<ACE_SV_Semaphore_Simple> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Read_Guard<ACE_SV_Semaphore_Simple> -<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/021/page04.html b/docs/tutorials/021/page04.html deleted file mode 100644 index cc6d3c0fa17..00000000000 --- a/docs/tutorials/021/page04.html +++ /dev/null @@ -1,88 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 021</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - Everything common the server & client is kept here. In - particular, the Constants class where we keep the names & - semaphore keys. - <p> - The Allocator class is just a thin wrapper around - ACE_Malloc<> that moves some of the details out of the - application logic. -<hr><PRE> - -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>MPOOL_H</font> -<font color=blue>#define</font> <font color=purple>MPOOL_H</font> - -<font color=red>// Everything else we need is in this one header</font> -<font color=blue>#include</font> "<font color=green>ace/Malloc.h</font>" - -<font color=red>/* - With this we will abstract away some of the details of the memory - pool. Note that we don't treat this as a singleton because an - application may need more than one pool. Each would have a - different name and be used for different purposes. - */</font> -class Allocator -{ -public: - <font color=red>// The pool name will be used to create a unique semaphore to</font> - <font color=red>// keep this pool separate from others.</font> - Allocator( const char * _name = "<font color=green>MemoryPool</font>" ); - ~Allocator(void); - - typedef ACE_Malloc<ACE_MMAP_Memory_Pool, ACE_SV_Semaphore_Simple> pool_t; - - <font color=red>// Provide an accessor to the pool. This will also allocate the</font> - <font color=red>// pool when first invoked.</font> - pool_t & pool(void); - -protected: - - <font color=red>// The name we gave to the pool</font> - char * name_; - - pool_t * pool_; -}; - -<font color=red>/* - The client and server need to agree on a certain set of values. By - placing them in the Constants class we can eliminate a bit of confusion. - */</font> -class Constants -{ -public: - <font color=red>// The semaphore keys are needed for the two semaphores that</font> - <font color=red>// synch access to the shared memory area.</font> - static const int SEM_KEY_1; - static const int SEM_KEY_2; - - <font color=red>// How big the pool will be and what we'll put into it. A real</font> - <font color=red>// app wouldn't need SHMDATA of course.</font> - static const int SHMSZ; - static const char * SHMDATA; - - <font color=red>// The name assigned to the memory pool by the server is needed</font> - <font color=red>// by the client. Without it, the pool cannot be found.</font> - <font color=red>// Likewise, the name the server will bind() to the region of the </font> - <font color=red>// pool must be available to the client.</font> - static const char * PoolName; - static const char * RegionName; -}; - -<font color=blue>#endif</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/021/page05.html b/docs/tutorials/021/page05.html deleted file mode 100644 index 6e238fcc85b..00000000000 --- a/docs/tutorials/021/page05.html +++ /dev/null @@ -1,91 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 021</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - Everything common the server & client is kept here. In - particular, the Constants class where we keep the names & - semaphore keys. - <p> - The Allocator class is just a thin wrapper around - ACE_Malloc<> that moves some of the details out of the - application logic. -<hr><PRE> - -<font color=red>// $Id$ </font> - -<font color=blue>#include</font> "<font color=green>mpool.h</font>" - -<font color=red>/* - Set the values of all of the constants. This guarantees that client - and server don't get confused. - */</font> -const int <font color=#008888>Constants::SEM_KEY_1</font> = ACE_DEFAULT_SEM_KEY + 1; -const int <font color=#008888>Constants::SEM_KEY_2</font> = ACE_DEFAULT_SEM_KEY + 2; - -const int <font color=#008888>Constants::SHMSZ</font> = 27; -const char * <font color=#008888>Constants::SHMDATA</font> = "<font color=green>abcdefghijklmnopqrstuvwxyz</font>"; - -const char * <font color=#008888>Constants::PoolName</font> = "<font color=green>SharedMemoryPool</font>"; -const char * <font color=#008888>Constants::RegionName</font> = "<font color=green>Alphabet</font>"; - -<font color=red>/* - We have to create a copy of the _name parameter in case the caller - has dynamically allocated it. The pool_ is set to NULL & will be - allocated by the accessor. - */</font> -<font color=#008888>Allocator::Allocator</font>( const char * _name ) - : name_(<font color=#008888>ACE_OS::strdup</font>(_name)), - pool_(0) -{ - if( ! name_ ) - { - ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p</font>", - "<font color=green><font color=#008888>Allocator::Allocator</font> cannot strdup pool name</font>" )); - } -} - -<font color=#008888>Allocator::~Allocator</font>(void) -{ - <font color=red>/* - strdup() uses malloc(), so we must use free() to clean up. - */</font> - if( name_ ) - { - free(name_); - } - - <font color=red>// delete doesn't really care if you give it a NULL pointer.</font> - delete pool_; -} - -<font color=red>/* - Allocate the pool. Since we return a reference, we'll be in really - bad shape if the new fails. This is a great place to throw an - exception! - The other concern is thread safety. If two threads call here at - about the same time, we may create the pool twice. We can't use a - Singleton because we want to have multiple Allocator instances. The - Singleton techniques can be used though. - */</font> -<font color=#008888>Allocator::pool_t</font> & Allocator::pool(void) -{ - if( ! pool_ ) - { - pool_ = new pool_t( name_ ); - } - - return *pool_; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/021/page06.html b/docs/tutorials/021/page06.html deleted file mode 100644 index 6b2b67963ef..00000000000 --- a/docs/tutorials/021/page06.html +++ /dev/null @@ -1,32 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 021</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 021</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Pooling your memories</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - As you can see, using a memory pool is really rather easy. The - most difficult part, as always, is with the synch mechanisms. - <P> - The other nice thing about ACE_Malloc<> is that you can swap - between System V shared memory and memory mapped files just by - changing the template parameters. The truly adventurous will - likely find a runtime way of doing this. - <p> - - <ul> - <li><A HREF="Makefile">Makefile</A> - <li><A HREF="server.cpp">server.cpp</A> - <li><A HREF="client.cpp">client.cpp</A> - <li><A HREF="mpool.h">mpool.h</A> - <li><A HREF="mpool.cpp">mpool.cpp</A> - </ul> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/021/server.cpp b/docs/tutorials/021/server.cpp deleted file mode 100644 index 5451e04d0ef..00000000000 --- a/docs/tutorials/021/server.cpp +++ /dev/null @@ -1,155 +0,0 @@ - -// $Id$ - -/* - I've hidden the details in an Allocator class declared in mpool.h - We'll come to that a little later. -*/ -#include "mpool.h" - -#if defined(ACE_LACKS_SYSV_SHMEM) -int main (int, char *[]) -{ - ACE_ERROR_RETURN ((LM_ERROR, "System V Semaphores not available on this platform.\n"),100); -} -#else // ACE_LACKS_SYSV_SHMEM -int main (int, char *[]) -{ - /* - Construction of an Allocator will create the memory pool and - provide it with a name. The Constants class is also - declared in mpool.h to keep server and client on the same - page. The name is used to generate a unique semaphore which - prevents simultaneous access to the pools housekeeping - information. (Note that you still have to provide your own - synch mechanisms for the data *you* put in the poo.) - */ - Allocator allocator(Constants::PoolName); - - /* - The Allocator class provides the pool() member so that you - have access to the actual memory pool. A more robust - implementation would behave more as a bridge class but this - is good enough for what we're doing here. - Once you have a reference to the pool, the malloc() method - can be used to get some bytes. If successful, shm will - point to the data. Otherwise, it will be zero. - */ - char *shm = (char *) allocator.pool().malloc (27); - - ACE_ASSERT( shm != 0 ); - - /// FYI - ACE_DEBUG ((LM_INFO, "Shared memory is at 0x%x\n", shm )); - - /* - Something that we can do with a memory pool is map a name to - a region provided by malloc. By doing this, we can - communicate that name to the client as a rendezvous - location. Again, a member of Constants is used to keep the - client and server coordinated. - */ - if( allocator.pool().bind(Constants::RegionName,shm) == -1 ) - { - ACE_ERROR_RETURN ((LM_ERROR, "Cannot bind the name '%s' to the pointer 0x%x\n", - Constants::RegionName,shm), 100 ); - } - - /* - One of the best ways to synch between different processes is - through the use of semaphores. ACE_SV_Semaphore_Complex - hides the gory details and lets us use them rather easily. - - Here, we'll create two semaphores: mutex and synch. mutex - will be used to provide mutually exclusive access to the - shared region for writting/reading. synch will be used to - prevent the server from removing the memory pool before the - client is done with it. - - Both semaphores are created in an initially locked state. - */ - - ACE_SV_Semaphore_Complex mutex; - ACE_ASSERT (mutex.open (Constants::SEM_KEY_1, - ACE_SV_Semaphore_Complex::ACE_CREATE, 0) != -1); - - ACE_SV_Semaphore_Complex synch; - ACE_ASSERT (synch.open (Constants::SEM_KEY_2, - ACE_SV_Semaphore_Complex::ACE_CREATE, 0) != -1); - - /* - We know the mutex is locked because we created it that way. - Take a moment to write some data into the shared region. - */ - for (int i = 0; i < Constants::SHMSZ; i++) - { - shm[i] = Constants::SHMDATA[i]; - } - - /* - The client will be blocking on an acquire() of mutex. By - releasing it here, the client can go look at the shared data. - */ - if (mutex.release () == -1) - { - ACE_ERROR ((LM_ERROR, "(%P) %p", "server mutex.release")); - } - /* - Even though we created the synch semaphore in a locked - state, if we attempt to acquire() it, we will block. Our - design requires that the client release() synch when it is - OK for us to remove the shared memory. - */ - else if (synch.acquire () == -1) - { - ACE_ERROR ((LM_ERROR, "(%P) %p", "server synch.acquire")); - } - - /* - This will remove all of the memory pool's resources. In the - case where a memory mapped file is used, the physical file - will also be removed. - */ - if (allocator.pool ().remove () == -1) - { - ACE_ERROR ((LM_ERROR, "(%P) %p\n", "server allocator.remove")); - } - - /* - We now have to cleanup the semaphores we created. Use the - ipcs command to see that they did, indeed, go away after the - server exits. - */ - - if (mutex.remove () == -1) - { - ACE_ERROR ((LM_ERROR, "(%P) %p\n", "server mutex.remove")); - } - - if (synch.remove () == -1) - { - ACE_ERROR ((LM_ERROR, "(%P) %p\n", "server synch.remove")); - } - - return 0; - -} - -/* - This tutorial was created by shamelessly modifying one of the ACE - examples. Someone there had already created the necessary explicit - template instantiations & I don't want them to go to waste... - */ -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple>; -template class ACE_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Write_Guard<ACE_SV_Semaphore_Simple>; -template class ACE_Read_Guard<ACE_SV_Semaphore_Simple>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Malloc<ACE_MMAP_MEMORY_POOL, ACE_SV_Semaphore_Simple> -#pragma instantiate ACE_Guard<ACE_SV_Semaphore_Simple> -#pragma instantiate ACE_Write_Guard<ACE_SV_Semaphore_Simple> -#pragma instantiate ACE_Read_Guard<ACE_SV_Semaphore_Simple> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - -#endif // ACE_LACKS_SYSV_SHMEM diff --git a/docs/tutorials/Chap_2/Chap_2.zip b/docs/tutorials/Chap_2/Chap_2.zip Binary files differdeleted file mode 100644 index e9201ef1925..00000000000 --- a/docs/tutorials/Chap_2/Chap_2.zip +++ /dev/null diff --git a/docs/tutorials/Chap_2/ex01.html b/docs/tutorials/Chap_2/ex01.html deleted file mode 100644 index 0de2788c3cf..00000000000 --- a/docs/tutorials/Chap_2/ex01.html +++ /dev/null @@ -1,106 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "IPC SAP" (Interprocess Communication -Mechanisms in ACE).</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#FF0000">//Example 1</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Stream.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">SIZE_DATA -18</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">SIZE_BUF -1024</FONT> - -<P>class Server{ - -<P>public: -<BR>Server (int port): -<BR> server_addr_(port),peer_acceptor_(server_addr_){ -<BR> data_buf_= new char[SIZE_BUF]; -<BR> } - -<P><FONT COLOR="#FF0000">//Handle the connection once it has been established.</FONT> -<BR><FONT COLOR="#FF0000">//Here the connection is handled by reading SIZE_DATA -amount of data</FONT> -<BR><FONT COLOR="#FF0000">//from the remote and then closing the connection</FONT> -<BR><FONT COLOR="#FF0000">//stream down.</FONT> -<BR>int handle_connection(){ -<BR> <FONT COLOR="#FF0000"> // Read data from client</FONT> -<BR> if(new_stream_.recv_n (data_buf_, SIZE_DATA, 0)==-1) -<BR> ACE_ERROR ((LM_ERROR, "%p\n", "Error in recv")); -<BR> - -<P> ACE_DEBUG((LM_DEBUG,"Server recieved %s \n",data_buf_)); -<BR> -<BR> <FONT COLOR="#FF0000">// Close new endpoint</FONT> -<BR> if (new_stream_.close () == -1) -<BR> ACE_ERROR ((LM_ERROR, "%p\n", "close")); -<BR> return 0; -<BR>} -<BR><FONT COLOR="#FF0000">//Use the acceptor component peer_acceptor_ to -accept the connection</FONT> -<BR><FONT COLOR="#FF0000">//into the underlying stream new_stream_. After -the connection has been</FONT> -<BR><FONT COLOR="#FF0000">//established call the handle_connenction() method.</FONT> -<BR>int accept_connections (){ -<BR> if (peer_acceptor_.get_local_addr (server_addr_) == -1) -<BR> ACE_ERROR_RETURN ((LM_ERROR,"%p\n","Error in get_local_addr"),1); - -<P> ACE_DEBUG ((LM_DEBUG,"Starting server at port %d\n", -<BR> server_addr_.get_port_number ())); -<BR> - -<P> <FONT COLOR="#FF0000">// Performs the iterative server activities.</FONT> -<BR> while(1){ -<BR> ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); -<BR> if (peer_acceptor_.accept -<BR> (new_stream_, &client_addr_, &timeout)== --1){ -<BR> ACE_ERROR ((LM_ERROR, "%p\n", "accept")); -<BR> continue; -<BR> } -<BR> else -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "Connection established with remote %s:%d\n", -<BR> client_addr_.get_host_name(),client_addr_.get_port_number())); -<BR> <FONT COLOR="#FF0000">//Handle the connection</FONT> -<BR> handle_connection(); -<BR> } -<BR> } -<BR> -<BR> - -<P>private: -<BR> char *data_buf_; -<BR> ACE_INET_Addr server_addr_; -<BR> ACE_INET_Addr client_addr_; -<BR> ACE_SOCK_Acceptor peer_acceptor_; -<BR> ACE_SOCK_Stream new_stream_; -<BR> ACE_HANDLE newhandle; -<BR>}; - -<P>int main (int argc, char *argv[]){ -<BR> if(argc<2){ -<BR> ACE_ERROR((LM_ERROR,"Usage egX <port_num>")); -<BR> ACE_OS::exit(1); -<BR> } -<BR> Server server(ACE_OS::atoi(argv[1])); -<BR> server.accept_connections(); -<BR>} - -<P> <A HREF="ex02.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_2/ex02.html b/docs/tutorials/Chap_2/ex02.html deleted file mode 100644 index 69891f26f1e..00000000000 --- a/docs/tutorials/Chap_2/ex02.html +++ /dev/null @@ -1,95 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 2</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "IPC SAP" (Interprocess -Communication Mechanisms in ACE).</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT><FONT COLOR="#FF0000"></FONT> - -<P><FONT COLOR="#FF0000">//</FONT><FONT COLOR="#CC0000">Example 2</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Connector.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/INET_Addr.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">SIZE_BUF -128</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">NO_ITERATIONS -5</FONT> - -<P>class Client{ -<BR>public: -<BR>Client(char *hostname, int port):remote_addr_(hostname){ -<BR> remote_addr_.set_port_number(port); -<BR> data_buf_=new char[SIZE_BUF]; -<BR> } - -<P><FONT COLOR="#FF0000">//Uses a connector component connector_ to connect -to a remote machine</FONT> -<BR><FONT COLOR="#FF0000">//and pass the connection into a stream component -client_stream_</FONT> -<BR>int connect_to_server(){ -<BR> <FONT COLOR="#FF0000">// Initiate blocking connection with server.</FONT> -<BR> ACE_DEBUG ((LM_DEBUG, "(%P|%t) Starting connect to %s:%d\n", -<BR> remote_addr_.get_host_name(),remote_addr_.get_port_number())); -<BR> if (connector_.connect (client_stream_, remote_addr_) == -1) -<BR> ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","connection -failed"),-1); -<BR> else -<BR> ACE_DEBUG ((LM_DEBUG,"(%P|%t) connected to %s\n", -<BR> remote_addr_.get_host_name ())); -<BR> return 0; -<BR> } - -<P><FONT COLOR="#FF0000">//Uses a stream component to send data to the -remote host.</FONT> -<BR>int send_to_server(){ -<BR> <FONT COLOR="#FF0000"> // Send data to server</FONT> -<BR> ACE_OS::sprintf(data_buf_,"Hello from Client"); -<BR> for(int i=0;i<NO_ITERATIONS; i++){ -<BR> if (client_stream_.send_n -<BR> (data_buf_, ACE_OS::strlen(data_buf_), 0) == -1){ -<BR> ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","send_n"),0); -<BR> break; -<BR> } -<BR> } -<BR> <FONT COLOR="#FF0000">//Close down the connection</FONT> -<BR> close(); -<BR>} - -<P><FONT COLOR="#FF0000">//Close down the connection properly.</FONT> -<BR>int close(){ -<BR> if (client_stream_.close () == -1) -<BR> ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","close"),-1); -<BR> else -<BR> return 0; -<BR> } - -<P>private: -<BR> ACE_SOCK_Stream client_stream_; -<BR> ACE_INET_Addr remote_addr_; -<BR> ACE_SOCK_Connector connector_; -<BR> char *data_buf_; -<BR>}; - -<P>int main (int argc, char *argv[]){ -<BR> if(argc<3){ -<BR> ACE_DEBUG((LM_DEBUG,?Usage egX <hostname> <port_number>\n?)); -<BR> ACE_OS::exit(1); -<BR> } -<BR> Client client(argv[1],ACE_OS::atoi(argv[2])); -<BR> client.connect_to_server(); -<BR> client.send_to_server(); -<BR>} - -<P> <A HREF="ex03.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_2/ex03.html b/docs/tutorials/Chap_2/ex03.html deleted file mode 100644 index 838eedcc81c..00000000000 --- a/docs/tutorials/Chap_2/ex03.html +++ /dev/null @@ -1,81 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 3</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "IPC SAP" (Interprocess -Communication Mechanisms in ACE).</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT><FONT COLOR="#FF0000"></FONT> - -<P><FONT COLOR="#CC0000">// Example 3</FONT><FONT COLOR="#FF0000"></FONT> - -<P><FONT COLOR="#FF0000">//Server</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Dgram.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/INET_Addr.h"</FONT> - -<P><FONT COLOR="#000099">#define </FONT><FONT COLOR="#663366">DATA_BUFFER_SIZE -1024</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">SIZE_DATA -18</FONT> - -<P>class Server{ -<BR>public: -<BR>Server(int local_port) -<BR> :local_addr_(local_port),local_(local_addr_){ -<BR> data_buf = new char[DATA_BUFFER_SIZE]; -<BR> } -<BR><FONT COLOR="#FF0000">//Expect data to arrive from the remote machine. -Accept it and display it.</FONT> -<BR><FONT COLOR="#FF0000">// After recieveing data immediately send some -data back to the remote.</FONT> -<BR>int accept_data(){ -<BR> while(local_.recv(data_buf,SIZE_DATA,remote_addr_)!=-1){ -<BR> ACE_DEBUG((LM_DEBUG, "Data received from remote %s was %s \n" -<BR> ,remote_addr_.get_host_name(), data_buf)); -<BR> ACE_OS::sleep(1); -<BR> if(send_data()==-1) break; -<BR> } -<BR> return -1; -<BR> } -<BR> -<BR> - -<P><FONT COLOR="#FF0000">//Method used to send data to the remote using -the datagram component local_</FONT> -<BR>int send_data(){ -<BR> ACE_DEBUG((LM_DEBUG,"Preparing to send reply to client %s:%d\n", -<BR> remote_addr_.get_host_name(),remote_addr_.get_port_number())); -<BR> ACE_OS::sprintf(data_buf,"Server says hello to you too"); -<BR> if( -<BR> local_.send(data_buf, ACE_OS::strlen(data_buf),remote_addr_)==-1) -<BR> return -1; -<BR> else -<BR> return 0; -<BR> } - -<P>private: -<BR> char *data_buf; -<BR> ACE_INET_Addr remote_addr_; -<BR> ACE_INET_Addr local_addr_; -<BR> ACE_SOCK_Dgram local_; -<BR>}; - -<P>int main(int argc, char *argv[]){ -<BR> Server server(ACE_OS::atoi(argv[1])); -<BR> server.accept_data(); -<BR>} - -<P> <A HREF="ex04.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_2/ex04.html b/docs/tutorials/Chap_2/ex04.html deleted file mode 100644 index 41cf78188bd..00000000000 --- a/docs/tutorials/Chap_2/ex04.html +++ /dev/null @@ -1,87 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 4</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "IPC SAP" (Interprocess Communication -Mechanisms in ACE).</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 4</FONT> -<BR><FONT COLOR="#FF0000">//Client</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Dgram.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/INET_Addr.h"</FONT> - -<P><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">DATA_BUFFER_SIZE -1024</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">SIZE_DATA -28</FONT> -<BR>class Client{ -<BR>public: -<BR>Client(char * remote_addr,int port) -<BR> :remote_addr_(remote_addr), -<BR> local_addr_((u_short)0),local_(local_addr_){ -<BR> data_buf = new char[DATA_BUFFER_SIZE]; -<BR> remote_addr_.set_port_number(port); -<BR> } -<BR> -<BR><FONT COLOR="#FF0000">//Accept data from the remote host using the -datgram component local_</FONT> -<BR>int accept_data(){ -<BR> if(local_.recv(data_buf,SIZE_DATA,remote_addr_)!=-1){ -<BR> ACE_DEBUG((LM_DEBUG, "Data received from remote server %s -<BR> was: %s \n" ,remote_addr_.get_host_name(), -data_buf)); -<BR> return 0; -<BR> } -<BR> else -<BR> return -1; -<BR> } - -<P><FONT COLOR="#FF0000">//Send data to the remote. Once data has been -sent wait for a reply from</FONT> -<BR><FONT COLOR="#FF0000">//the server.</FONT> -<BR>int send_data(){ -<BR> ACE_DEBUG((LM_DEBUG,"Preparing to send data to server %s:%d\n", -<BR> remote_addr_.get_host_name(),remote_addr_.get_port_number())); -<BR> ACE_OS::sprintf(data_buf,"Client says hello"); -<BR> -<BR> while(local_.send -<BR> (data_buf,ACE_OS::strlen(data_buf),remote_addr_)!=-1){ -<BR> ACE_OS::sleep(1); -<BR> if(accept_data()==-1) -<BR> break; -<BR> } -<BR> return -1; -<BR> } - -<P>private: -<BR> char *data_buf; -<BR> ACE_INET_Addr remote_addr_; -<BR> ACE_INET_Addr local_addr_; -<BR> ACE_SOCK_Dgram local_; -<BR>}; - -<P>int main(int argc, char *argv[]){ -<BR>if(argc<3){ -<BR> ACE_OS::printf("Usage: Client hostname port_number \n"); -<BR> ACE_OS::exit(1); -<BR> } -<BR>Client client(argv[1],ACE_OS::atoi(argv[2])); -<BR>client.send_data(); -<BR>} -<BR> -<BR> <A HREF="ex05.htm">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_2/ex05.htm b/docs/tutorials/Chap_2/ex05.htm deleted file mode 100644 index 1a88e7c8dbd..00000000000 --- a/docs/tutorials/Chap_2/ex05.htm +++ /dev/null @@ -1,87 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 5</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "IPC SAP" (Interprocess Communication -Mechanisms in ACE).</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 5</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Dgram_Mcast.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">DEFAULT_MULTICAST_ADDR -"224.9.9.2"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">TIMEOUT -5</FONT> - -<P>class Reciever_Multicast{ - -<P>public: -<BR>Reciever_Multicast(int port): -<BR> mcast_addr_(port,DEFAULT_MULTICAST_ADDR),remote_addr_((u_short)0){ -<BR> <FONT COLOR="#FF0000"> // Subscribe to multicast address.</FONT> -<BR> if (mcast_dgram_.subscribe (mcast_addr_) == -1){ -<BR> ACE_DEBUG((LM_DEBUG,"Error in subscribing to Multicast address -\n")); -<BR> exit(-1); -<BR> } -<BR>} - -<P>~Reciever_Multicast(){ -<BR> if(mcast_dgram_.unsubscribe()==-1) -<BR> ACE_DEBUG((LM_ERROR,?Error in unsubscribing from Mcast group\n?)); -<BR> } -<BR> -<BR> -<BR> - -<P><FONT COLOR="#FF0000">//Receive data from someone who is sending data -on the multicast group</FONT> -<BR><FONT COLOR="#FF0000">//address to do so it must use the multicast -datagram component</FONT> -<BR><FONT COLOR="#FF0000">//mcast_dgram_.</FONT> -<BR>int recv_multicast(){ -<BR><FONT COLOR="#FF0000"> //get ready to recieve data from the sender.</FONT> -<BR> if(mcast_dgram_.recv -<BR> (&mcast_info,sizeof (mcast_info),remote_addr_)==-1) -<BR> return -1; -<BR> ACE_DEBUG ((LM_DEBUG, "(%P|%t) Received multicast from %s:%d.\n", -<BR> remote_addr_.get_host_name(), remote_addr_.get_port_number())); -<BR> ACE_DEBUG((LM_DEBUG,"Successfully receieved %d\n", mcast_info)); -<BR> return 0; -<BR> } - -<P>private: -<BR> ACE_INET_Addr mcast_addr_; -<BR> ACE_INET_Addr remote_addr_; -<BR> ACE_SOCK_Dgram_Mcast mcast_dgram_; -<BR> int mcast_info; -<BR>}; -<BR> -<BR> -<BR>int main(int argc, char*argv[]){ -<BR> Reciever_Multicast m(2000); -<BR> <FONT COLOR="#FF0000">//Will run forever</FONT> -<BR> while(m.recv_multicast()!=-1) { -<BR> ACE_DEBUG((LM_DEBUG,"Multicaster succesful \n")); -<BR> } -<BR> -<BR> ACE_DEBUG((LM_ERROR,"Multicaster failed \n")); -<BR> exit(-1); -<BR>} - -<P> <A HREF="ex06.html">Next Example</A> -<BR> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_2/ex06.html b/docs/tutorials/Chap_2/ex06.html deleted file mode 100644 index 94f40443766..00000000000 --- a/docs/tutorials/Chap_2/ex06.html +++ /dev/null @@ -1,76 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 6</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "IPC SAP" (Interprocess Communication -Mechanisms in ACE).</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 6</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">DEFAULT_MULTICAST_ADDR -"224.9.9.2"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">TIMEOUT -5</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/SOCK_Dgram_Mcast.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> - -<P>class Sender_Multicast{ -<BR>public: -<BR>Sender_Multicast(int port): -<BR> local_addr_((u_short)0),dgram_(local_addr_), -<BR> multicast_addr_(port,DEFAULT_MULTICAST_ADDR){} - -<P><FONT COLOR="#FF0000">//Method which uses a simple datagram component -to send data to the multicast group.</FONT> -<BR>int send_to_multicast_group(){ -<BR> <FONT COLOR="#FF0000">//Convert the information we wish -to send into network byte order</FONT> -<BR> mcast_info= htons (1000); - -<P><FONT COLOR="#FF0000"> // Send multicast</FONT> -<BR> if(dgram_.send -<BR> (&mcast_info, sizeof (mcast_info), multicast_addr_)==-1) -<BR> return -1; - -<P> ACE_DEBUG ((LM_DEBUG, -<BR> -"%s; Sent multicast to group. Number sent is %d.\n", -<BR> -__FILE__, -<BR> -mcast_info)); -<BR> return 0; -<BR>} - -<P>private: -<BR> ACE_INET_Addr multicast_addr_; -<BR> ACE_INET_Addr local_addr_; -<BR> ACE_SOCK_Dgram dgram_; -<BR> int mcast_info; -<BR>}; -<BR> - -<P>int main(int argc, char*argv[]){ -<BR>Sender_Multicast m(2000); -<BR>if(m.send_to_multicast_group()==-1) { -<BR> ACE_DEBUG((LM_ERROR,"Send to Multicast group failed \n")); -<BR> exit(-1); -<BR> } -<BR>else -<BR> ACE_DEBUG((LM_DEBUG,"Send to Multicast group succesful \n")); -<BR>} - -<P> <A HREF="../Chap_3/ex01.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_3/Chap_3.zip b/docs/tutorials/Chap_3/Chap_3.zip Binary files differdeleted file mode 100644 index c99463d18d9..00000000000 --- a/docs/tutorials/Chap_3/Chap_3.zip +++ /dev/null diff --git a/docs/tutorials/Chap_3/ex01.html b/docs/tutorials/Chap_3/ex01.html deleted file mode 100644 index a722e9a9b6d..00000000000 --- a/docs/tutorials/Chap_3/ex01.html +++ /dev/null @@ -1,107 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 1</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Memory Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 1 </FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Malloc.h"</FONT> -<BR><FONT COLOR="#FF0000">//A chunk of size 1K is created</FONT> -<BR><FONT COLOR="#000099">typedef</FONT> <FONT COLOR="#993300">char</FONT><FONT COLOR="#666600"> -MEMORY_BLOCK[1024];</FONT> -<BR> -<BR> - -<P><FONT COLOR="#FF0000">//Create an ACE_Cached_Allocator which is passed -in the type of the</FONT> -<BR><FONT COLOR="#FF0000">//chunk that it must pre-allocate and assign -on the free</FONT> -<BR><FONT COLOR="#FF0000">//list</FONT> -<BR><FONT COLOR="#000000">typedef ACE_Cached_Allocator<MEMORY_BLOCK,ACE_SYNCH_MUTEX> -Allocator;</FONT> -<BR> -<BR>class MessageManager{ -<BR>public: -<BR><FONT COLOR="#FF0000">//The constructor is passed the number of chunks -that the allocator should pre-allocate //and maintain on its free list.</FONT> -<BR>MessageManager(int n_blocks): -<BR> allocator_(n_blocks),message_count_(0){} - -<P><FONT COLOR="#FF0000">//Allocate memory for a message using the Allocator</FONT> -<BR>void allocate_msg(const char *msg){ -<BR> mesg_array_[message_count_]= -<BR> (char*)allocator_.malloc(ACE_OS::strlen(msg)); -<BR> ACE_OS::strcpy(mesg_array_[message_count_],msg); -<BR> message_count_++; -<BR> } - -<P><FONT COLOR="#FF0000">//Free all memory allocated. This will cause the -chunks to be returned</FONT> -<BR><FONT COLOR="#FF0000">//to the allocators internal free list and NOT -to the OS.</FONT> -<BR>void free_all_msg(){ -<BR> for(int i=0;i<message_count_;i++) -<BR> allocator_.free(mesg_array_[i]); -<BR> message_count_=0; -<BR> } -<BR>void display_all_msg(){ -<BR> for(int i=0;i<message_count_;i++) -<BR> ACE_OS::printf("%s\n",mesg_array_[i]); -<BR> } -<BR> -<BR>private: -<BR> char *mesg_array_[20]; -<BR> Allocator allocator_; -<BR> int message_count_; -<BR>}; -<BR> - -<P>int main(int argc, char* argv[]){ - -<P>if(argc<2){ -<BR> ACE_OS::printf("Usage: egXX <Number of blocks>\n"); -<BR> exit(1); -<BR> } -<BR> -<BR><FONT COLOR="#FF0000">//Instatiate the Memory Manager class</FONT> -<BR>int n_blocks=ACE_OS::atoi(argv[1]); -<BR>MessageManager mm(n_blocks); -<BR> - -<P><FONT COLOR="#FF0000">//Use the Memory Manager class to assign messages -and free them.</FONT> <FONT COLOR="#FF0000">Run this in your</FONT> -<BR><FONT COLOR="#FF0000">//debug environment and you will notice that -//the</FONT> <FONT COLOR="#FF0000">amount of memory your program uses</FONT> -<BR><FONT COLOR="#FF0000">//after Memory Manager has been</FONT> <FONT COLOR="#FF0000">instantiated -remains the same. That means the</FONT> -<BR><FONT COLOR="#FF0000">//Cached Allocator</FONT> <FONT COLOR="#FF0000">controls -or manages all the memory for the application.</FONT> - -<P><FONT COLOR="#FF0000">//Do forever.</FONT> -<BR>while(1){ -<BR> <FONT COLOR="#FF0000">//allocate the messages somewhere</FONT> -<BR> for(int i=0; i<n_blocks;i++) -<BR> mm.allocate_msg("Hi there"); -<BR> <FONT COLOR="#FF0000">//show the messages</FONT> -<BR> mm.display_all_msg(); -<BR> -<BR> for( i=0;i<n_blocks;i++) -<BR> mm.free_all_msg(); -<BR> } -<BR>} - -<P> <A HREF="ex02.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_3/ex02.html b/docs/tutorials/Chap_3/ex02.html deleted file mode 100644 index b425bfb9565..00000000000 --- a/docs/tutorials/Chap_3/ex02.html +++ /dev/null @@ -1,135 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 2</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Memory Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 2</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Shared_Memory_MM.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Malloc.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Malloc_T.h"</FONT> -<BR><FONT COLOR="#000099">#define </FONT><FONT COLOR="#663366">DATA_SIZE -100</FONT> -<BR><FONT COLOR="#000099">#define</FONT><FONT COLOR="#663366"> MESSAGE1 -"Hiya over there client process"</FONT> -<BR><FONT COLOR="#000099">#define </FONT><FONT COLOR="#663366">MESSAGE2 -"Did you hear me the first time?"</FONT> -<BR>LPCTSTR poolname="My_Pool"; - -<P><FONT COLOR="#000000">typedef ACE_Malloc<ACE_SHARED_MEMORY_POOL,ACE_Null_Mutex> -Malloc_Allocator;</FONT> - -<P>static void -<BR>server (void){ -<BR> <FONT COLOR="#FF0000">//Create the memory allocator passing it -the shared memory</FONT> -<BR> <FONT COLOR="#FF0000">//pool that you want to use</FONT> -<BR> Malloc_Allocator shm_allocator(poolname); - -<P> <FONT COLOR="#FF0000">//Create a message, allocate memory for -it and bind it with</FONT> -<BR><FONT COLOR="#FF0000"> //a name so that the client can the find -it in the memory</FONT> -<BR><FONT COLOR="#FF0000"> //pool</FONT> -<BR> char* Message1=(char*)shm_allocator.malloc(strlen(MESSAGE1)); -<BR> ACE_OS::strcpy(Message1,MESSAGE1); -<BR> shm_allocator.bind("FirstMessage",Message1); -<BR> ACE_DEBUG((LM_DEBUG,"<<%s\n",Message1)); -<BR> -<BR><FONT COLOR="#FF0000"> //How about a second message</FONT> -<BR> char* Message2=(char*)shm_allocator.malloc(strlen(MESSAGE2)); -<BR> ACE_OS::strcpy(Message2,MESSAGE2); -<BR> shm_allocator.bind("SecondMessage",Message2); -<BR> ACE_DEBUG((LM_DEBUG,"<<%s\n",Message2)); -<BR> -<BR> <FONT COLOR="#FF0000">//Set the Server to go to sleep for a while -so that the client has</FONT> -<BR><FONT COLOR="#FF0000"> //a chance to do its stuff</FONT> -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "Server done writing.. going to sleep zzz..\n\n\n")); -<BR> ACE_OS::sleep(2); -<BR> -<BR><FONT COLOR="#FF0000"> //Get rid of all resources allocated by -the server. In other</FONT> -<BR><FONT COLOR="#FF0000"> //words get rid of the shared memory pool -that had been</FONT> -<BR><FONT COLOR="#FF0000"> //previously allocated</FONT> -<BR> shm_allocator.remove(); -<BR> -<BR>} -<BR> - -<P>static void -<BR>client(void){ -<BR> <FONT COLOR="#FF0000">//Create a memory allocator. Be sure that -the client passes</FONT> -<BR><FONT COLOR="#FF0000"> // in the "right" name here so that both -the client and the</FONT> -<BR><FONT COLOR="#FF0000"> //server use the same memory pool. We wouldnt -want them to</FONT> -<BR><FONT COLOR="#FF0000"> // BOTH create different underlying pools.</FONT> -<BR> Malloc_Allocator shm_allocator(poolname); - -<P><FONT COLOR="#FF0000"> //Lets get that first message. Notice that -the find is looking up the</FONT> -<BR><FONT COLOR="#FF0000"> //memory based on the "name" that was bound -to it by the server.</FONT> -<BR> void *Message1; -<BR> if(shm_allocator.find("FirstMessage",Message1)==-1){ -<BR> ACE_ERROR((LM_ERROR, -<BR> "Client: Problem cant find data that server has -sent\n")); -<BR> ACE_OS::exit(1); -<BR> } -<BR> ACE_OS::printf(">>%s\n",(char*) Message1); -<BR> ACE_OS::fflush(stdout); - -<P> <FONT COLOR="#FF0000">//Lets get that second message now.</FONT> -<BR> void *Message2; -<BR> if(shm_allocator.find("SecondMessage",Message2)==-1){ -<BR> ACE_ERROR((LM_ERROR,"Client: Problem cant find data that server -has sent\n")); -<BR> ACE_OS::exit(1); -<BR> } -<BR> ACE_OS::printf(">>%s\n",(char*)Message2); -<BR> ACE_OS::fflush(stdout); - -<P> ACE_DEBUG((LM_DEBUG,"Client done reading! BYE NOW\n")); -<BR> ACE_OS::fflush(stdout); -<BR>} -<BR> - -<P>int main (int, char *[]){ -<BR>switch (ACE_OS::fork ()) -<BR> { -<BR> case -1: -<BR> ACE_ERROR_RETURN ((LM_ERROR, "%p\n", -"fork"), 1); -<BR> case 0: -<BR> <FONT COLOR="#FF0000"> // Make sure the -server starts up first.</FONT> -<BR> ACE_OS::sleep (1); -<BR> client (); -<BR> break; -<BR> default: -<BR> server (); -<BR> break; -<BR> } -<BR> return 0; -<BR>} -<BR> -<BR> <A HREF="../Chap_4/ex01.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/Chap_4.zip b/docs/tutorials/Chap_4/Chap_4.zip Binary files differdeleted file mode 100644 index b29059f1457..00000000000 --- a/docs/tutorials/Chap_4/Chap_4.zip +++ /dev/null diff --git a/docs/tutorials/Chap_4/ex01.html b/docs/tutorials/Chap_4/ex01.html deleted file mode 100644 index 00e8cb8f51d..00000000000 --- a/docs/tutorials/Chap_4/ex01.html +++ /dev/null @@ -1,74 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 1</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 1</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Thread.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch_T.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Synch.h"</FONT> -<BR>static int number=0; -<BR>static int seed=0; - -<P>static void* -<BR>worker(void *arg){ -<BR> ACE_UNUSED_ARG(arg); -<BR> ACE_DEBUG((LM_DEBUG,"Thread (%t) Created to do some work")); -<BR> ::number++; -<BR> ACE_DEBUG((LM_DEBUG," and number is %d\n",::number)); -<BR> -<BR> <FONT COLOR="#FF0000">//Let the other guy go while I fall asleep -for a random period of time</FONT> -<BR> ACE_Thread::yield(); -<BR> ACE_OS::sleep(ACE_OS::rand()%2); - -<P><FONT COLOR="#FF0000"> //Exiting now</FONT> -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "\t\t Thread (%t) Done! \t The number is now: %d\n",number)); -<BR> ACE_OS::fflush(stdout); -<BR> return 0; -<BR> } -<BR> - -<P>int main(int argc, char *argv[]){ -<BR>if(argc<2) -<BR> ACE_DEBUG((LM_DEBUG,"Usage: <program_name> <number of threads>\n")); -<BR> -<BR>int n_threads=ACE_OS::atoi(argv[1]); -<BR><FONT COLOR="#FF0000">//Setup the random number generator</FONT> -<BR>ACE_OS::srand(::seed); - -<P><FONT COLOR="#FF0000">//Spawn off n_threads number of threads</FONT> -<BR>for(int i=0; i<n_threads; i++){ -<BR> if(ACE_Thread::spawn((ACE_THR_FUNC)worker)==-1) -<BR> ACE_DEBUG((LM_DEBUG,"Error in spawning thread\n")); -<BR> } - -<P><FONT COLOR="#FF0000">//Wait for all the threads to exit before you -let the main fall through</FONT> -<BR><FONT COLOR="#FF0000">//and have the process exit. This way of using -join is non-portable</FONT> -<BR><FONT COLOR="#FF0000">//and may not work on a system using pthreads.</FONT> -<BR>int check_count=0; -<BR>while(ACE_Thread::join(NULL,NULL,NULL)==0) check_count++; -<BR>ACE_ASSERT(check_count==n_threads); -<BR>} - -<P> <A HREF="ex02.html">Next Example</A> -<BR> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/ex02.html b/docs/tutorials/Chap_4/ex02.html deleted file mode 100644 index 4feefe6dbe5..00000000000 --- a/docs/tutorials/Chap_4/ex02.html +++ /dev/null @@ -1,67 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 2</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 2</FONT> -<BR><FONT COLOR="#000099">#include </FONT><FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> - -<P><FONT COLOR="#FF0000">//Arguments that are to be passed to the worker -thread are passed through this class.</FONT> -<BR>class Args{ -<BR>public: -<BR>Args(int iterations): -<BR> mutex_(),iterations_(iterations){} -<BR>ACE_Thread_Mutex mutex_; -<BR>int iterations_; -<BR>}; - -<P><FONT COLOR="#FF0000">//The starting point for the worker threads</FONT> -<BR>static void* -<BR>worker(void*arguments){ -<BR>Args *arg= (Args*) arguments; -<BR>for(int i=0;i<arg->iterations_;i++){ -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "(%t) Trying to get a hold of this iteration\n")); -<BR><FONT COLOR="#FF0000"> //This is our critical section</FONT> -<BR> arg->mutex_.acquire(); -<BR> ACE_DEBUG((LM_DEBUG,"(%t) This is iteration number %d\n",i)); -<BR><FONT COLOR="#FF0000"> //work</FONT> -<BR> ACE_OS::sleep(2); -<BR> arg->mutex_.release(); -<BR> } -<BR>return 0; -<BR>} - -<P>int main(int argc, char*argv[]){ -<BR>if(argc<2){ -<BR>ACE_OS::printf("Usage: egx <number_of_threads> -<BR> <number_of_iterations>\n"); -<BR> ACE_OS::exit(1); -<BR> } -<BR><FONT COLOR="#FF0000">//Setup the arguments</FONT> -<BR>Args arg(ACE_OS::atoi(argv[2])); - -<P>ACE_Thread::spawn_n -<BR> (ACE_OS::atoi(argv[1]),(ACE_THR_FUNC)worker,(void*)&arg); -<BR><FONT COLOR="#FF0000">//Spawn the worker threads</FONT> -<BR>while(ACE_Thread::join(NULL,NULL,NULL)==0); -<BR>} -<BR> -<BR> <A HREF="ex03.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/ex03.html b/docs/tutorials/Chap_4/ex03.html deleted file mode 100644 index 56fbd9441aa..00000000000 --- a/docs/tutorials/Chap_4/ex03.html +++ /dev/null @@ -1,78 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 3</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 3</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch_T.h"</FONT> - -<P><FONT COLOR="#FF0000">//Arguments that are to be passed to the worker -thread are passed through this class.</FONT> -<BR>class Args{ -<BR>public: -<BR>Args(ACE_Lock* lock,int iterations): -<BR> mutex_(lock),iterations_(iterations){} -<BR>ACE_Lock* mutex_; -<BR>int iterations_; -<BR>}; - -<P><FONT COLOR="#FF0000">//The starting point for the worker threads</FONT> -<BR>static void* -<BR>worker(void*arguments){ -<BR>Args *arg= (Args*) arguments; -<BR>for(int i=0;i<arg->iterations_;i++){ -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "(%t) Trying to get a hold of this iteration\n")); -<BR><FONT COLOR="#FF0000"> //This is our critical section</FONT> -<BR> arg->mutex_->acquire(); -<BR> ACE_DEBUG((LM_DEBUG,"(%t) This is iteration number %d\n",i)); -<BR><FONT COLOR="#FF0000"> //work</FONT> -<BR> ACE_OS::sleep(2); -<BR> arg->mutex_->release(); -<BR> } -<BR>return 0; -<BR>} - -<P>int main(int argc, char*argv[]){ -<BR>if(argc<4){ -<BR> ACE_OS::printf("Usage: egx <number_of_threads> -<BR> <number_of_iterations> <lock_type>\n"); -<BR> ACE_OS::exit(1); -<BR> } -<BR><FONT COLOR="#FF0000">//Lock used by application</FONT> -<BR>ACE_Lock *lock; - -<P><FONT COLOR="#FF0000">//Decide which lock you want to use at run time. -Possible due to</FONT> -<BR><FONT COLOR="#FF0000">//ACE_Lock.</FONT> -<BR>if(ACE_OS::strcmp(argv[3],"Thread")) -<BR> lock=new ACE_Lock_Adapter<ACE_Thread_Mutex>; -<BR>else -<BR> lock=new ACE_Lock_Adapter<ACE_Mutex> - -<P><FONT COLOR="#FF0000">//Setup the arguments</FONT> -<BR>Args arg(lock,ACE_OS::atoi(argv[2])); -<BR><FONT COLOR="#FF0000">//Spawn the worker threads</FONT> -<BR>ACE_Thread::spawn_n -<BR> (ACE_OS::atoi(argv[1]),(ACE_THR_FUNC)worker,(void*)&arg); -<BR>while(ACE_Thread::join(NULL,NULL,NULL)==0); -<BR>} - -<P> <A HREF="ex04.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/ex04.html b/docs/tutorials/Chap_4/ex04.html deleted file mode 100644 index 091433ba5be..00000000000 --- a/docs/tutorials/Chap_4/ex04.html +++ /dev/null @@ -1,69 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 4</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 4</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Token.h"</FONT> - -<P><FONT COLOR="#FF0000">//Arguments that are to be passed to the worker -thread are passed</FONT> -<BR><FONT COLOR="#FF0000">//through this class.</FONT> -<BR>class Args{ -<BR>public: -<BR>Args(int iterations): -<BR> mutex_(),iterations_(iterations){} -<BR>ACE_Token mutex_; -<BR>int iterations_; -<BR>}; - -<P><FONT COLOR="#FF0000">//The starting point for the worker threads</FONT> -<BR>static void* -<BR>worker(void*arguments){ -<BR>Args *arg= (Args*) arguments; -<BR>for(int i=0;i<arg->iterations_;i++){ -<BR> ACE_DEBUG((LM_DEBUG,"(%t) Trying to get a hold of this iteration\n")); -<BR><FONT COLOR="#FF0000"> //This is our critical section</FONT> -<BR> arg->mutex_.acquire(); -<BR> ACE_DEBUG((LM_DEBUG,"(%t) This is iteration number %d\n",i)); -<BR><FONT COLOR="#FF0000"> //work</FONT> -<BR> ACE_OS::sleep(2); -<BR> arg->mutex_.release(); -<BR> } -<BR>return 0; -<BR>} -<BR> - -<P>int main(int argc, char*argv[]){ -<BR>if(argc<4){ -<BR> ACE_OS::printf("Usage: egx <number_of_threads> -<BR> <number_of_iterations> <lock_type>\n"); -<BR> ACE_OS::exit(1); -<BR> } - -<P><FONT COLOR="#FF0000">//Setup the arguments</FONT> -<BR>Args arg(ACE_OS::atoi(argv[2])); -<BR><FONT COLOR="#FF0000">//Spawn the worker threads</FONT> -<BR>ACE_Thread::spawn_n(ACE_OS::atoi(argv[1]),(ACE_THR_FUNC)worker,(void*)&arg); - -<P>while(ACE_Thread::join(NULL,NULL,NULL)==0); - -<P>} - -<P> <A HREF="ex05.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/ex05.html b/docs/tutorials/Chap_4/ex05.html deleted file mode 100644 index 74fbb7cd80f..00000000000 --- a/docs/tutorials/Chap_4/ex05.html +++ /dev/null @@ -1,69 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 5</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 5</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch_T.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Token.h"</FONT> - -<P><FONT COLOR="#FF0000">//Arguments that are to be passed to the worker -thread are passed through this class.</FONT> -<BR>class Args{ -<BR>public: -<BR>Args(int iterations): -<BR> mutex_(),iterations_(iterations){} -<BR>ACE_Token mutex_; -<BR>int iterations_; -<BR>}; - -<P><FONT COLOR="#FF0000">//The starting point for the worker threads</FONT> -<BR>static void* -<BR>worker(void*arguments){ -<BR>Args *arg= (Args*) arguments; -<BR>for(int i=0;i<arg->iterations_;i++){ -<BR> ACE_DEBUG((LM_DEBUG,"(%t) Trying to get a hold of this iteration\n")); -<BR> {<FONT COLOR="#FF0000">//begin critical section</FONT> -<BR> ACE_Guard<ACE_Token> guard(arg->mutex_); -<BR> <FONT COLOR="#FF0000"> //This is our critical section</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"(%t) This is iteration number %d\n",i)); -<BR><FONT COLOR="#FF0000"> //work</FONT> -<BR> ACE_OS::sleep(2); -<BR> }<FONT COLOR="#FF0000">//end critical section</FONT> -<BR> } -<BR>return 0; -<BR>} -<BR> - -<P>int main(int argc, char*argv[]){ -<BR>if(argc<3){ -<BR> ACE_OS::printf("Usage: egx <number_of_threads> <number_of_iterations> -\n"); -<BR> ACE_OS::exit(1); -<BR> } - -<P><FONT COLOR="#FF0000">//Setup the arguments</FONT> -<BR>Args arg(ACE_OS::atoi(argv[2])); -<BR><FONT COLOR="#FF0000">//Spawn the worker threads</FONT> -<BR>ACE_Thread::spawn_n(ACE_OS::atoi(argv[1]),(ACE_THR_FUNC)worker,(void*)&arg); -<BR>while(ACE_Thread::join(NULL,NULL,NULL)==0); -<BR>} - -<P> <A HREF="ex06.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/ex06.html b/docs/tutorials/Chap_4/ex06.html deleted file mode 100644 index 7a8df16dcd3..00000000000 --- a/docs/tutorials/Chap_4/ex06.html +++ /dev/null @@ -1,95 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 6</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 6</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Thread.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include </FONT><FONT COLOR="#006600">"ace/Synch_T.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Synch.h"</FONT> - -<P>static int number=0; -<BR>static int seed=0; - -<P>class Args{ -<BR>public: -<BR>Args(ACE_Condition<ACE_Thread_Mutex> *cond, int threads): -<BR> cond_(cond), threads_(threads){} -<BR>ACE_Condition<ACE_Thread_Mutex> *cond_; -<BR>int threads_; -<BR>}; - -<P>static void* -<BR>worker(void *arguments){ -<BR> Args *arg= (Args*)arguments; -<BR> ACE_DEBUG((LM_DEBUG,"Thread (%t) Created to do some work\n")); -<BR> ::number++; -<BR><FONT COLOR="#FF0000"> //Work</FONT> -<BR> ACE_OS::sleep(ACE_OS::rand()%2); - -<P><FONT COLOR="#FF0000"> //Exiting now</FONT> -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "\tThread (%t) Done! \n\tThe number is now: %d\n",number)); -<BR><FONT COLOR="#FF0000"> //If all threads are done signal main thread -that program can now exit</FONT> -<BR> if(number==arg->threads_){ -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "(%t) Last Thread!\n All threads have done -their job! -<BR> Signal main thread\n")); -<BR> arg->cond_->signal(); -<BR> } -<BR>return 0; -<BR>} -<BR> - -<P>int main(int argc, char *argv[]){ -<BR>if(argc<2){ -<BR> ACE_DEBUG((LM_DEBUG,"Usage: <program_name> <number of threads>\n")); -<BR> ACE_OS::exit(1); -<BR> } -<BR> -<BR>int n_threads=ACE_OS::atoi(argv[1]); - -<P><FONT COLOR="#FF0000">//Setup the random number generator</FONT> -<BR>ACE_OS::srand(::seed); - -<P><FONT COLOR="#FF0000">//Setup arguments for threads</FONT> -<BR>ACE_Thread_Mutex mutex; -<BR>ACE_Condition<ACE_Thread_Mutex> cond(mutex); -<BR>Args arg(&cond,n_threads); - -<P><FONT COLOR="#FF0000">//Spawn off n_threads number of threads</FONT> -<BR>for(int i=0; i<n_threads; i++){ -<BR> if(ACE_Thread::spawn((ACE_THR_FUNC)worker,(void*)&arg, -<BR> THR_DETACHED|THR_NEW_LWP)==-1) -<BR> ACE_DEBUG((LM_DEBUG,"Error in spawning thread\n")); -<BR> } - -<P><FONT COLOR="#FF0000">//Wait for signal indicating that all threads -are done and program can exit</FONT> -<BR>mutex.acquire(); -<BR>if(number!=n_threads) -<BR> cond.wait(); -<BR>ACE_DEBUG((LM_DEBUG,"(%t) Main Thread got signal. Program exiting..\n")); -<BR>mutex.release(); -<BR>ACE_OS::exit(0); -<BR>} - -<P> <A HREF="ex07.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/ex07.html b/docs/tutorials/Chap_4/ex07.html deleted file mode 100644 index 4adf56569d3..00000000000 --- a/docs/tutorials/Chap_4/ex07.html +++ /dev/null @@ -1,84 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 7</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 7</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Thread.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/OS.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch_T.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> - -<P>static int number=0; -<BR>static int seed=0; - -<P>class Args{ -<BR>public: -<BR>Args(ACE_Barrier *barrier): -<BR> barrier_(barrier){} -<BR>ACE_Barrier *barrier_; -<BR>}; - -<P>static void* -<BR>worker(void *arguments){ -<BR> Args *arg= (Args*)arguments; -<BR> ACE_DEBUG((LM_DEBUG,"Thread (%t) Created to do some work\n")); -<BR> ::number++; -<BR> -<BR><FONT COLOR="#FF0000"> //Work</FONT> -<BR> ACE_OS::sleep(ACE_OS::rand()%2); - -<P><FONT COLOR="#FF0000"> //Exiting now</FONT> -<BR> ACE_DEBUG((LM_DEBUG, -<BR> "\tThread (%t) Done! \n\tThe number is now: %d\n",number)); -<BR><FONT COLOR="#FF0000"> //Let the barrier know we are done.</FONT> -<BR> arg->barrier_->wait(); -<BR> ACE_DEBUG((LM_DEBUG,"Thread (%t) is exiting \n")); -<BR> return 0; -<BR>} -<BR> - -<P>int main(int argc, char *argv[]){ -<BR>if(argc<2){ -<BR> ACE_DEBUG((LM_DEBUG,"Usage: <program_name> <number of threads>\n")); -<BR> ACE_OS::exit(1); -<BR> } -<BR> -<BR>int n_threads=ACE_OS::atoi(argv[1]); -<BR>ACE_DEBUG((LM_DEBUG,"Preparing to spawn %d threads",n_threads)); -<BR><FONT COLOR="#FF0000">//Setup the random number generator</FONT> -<BR>ACE_OS::srand(::seed); - -<P><FONT COLOR="#FF0000">//Setup arguments for threads</FONT> -<BR>ACE_Barrier barrier(n_threads); -<BR>Args arg(&barrier); - -<P><FONT COLOR="#FF0000">//Spawn off n_threads number of threads</FONT> -<BR>for(int i=0; i<n_threads; i++){ if(ACE_Thread::spawn((ACE_THR_FUNC)worker,(void*)&arg,THR_DETACHED|THR_NEW_LWP)==-1) -<BR> ACE_DEBUG((LM_DEBUG,"Error in spawning thread\n")); -<BR> } - -<P><FONT COLOR="#FF0000">//Wait for all the other threads to let the main -thread</FONT> -<BR><FONT COLOR="#FF0000">// know that they are done using hte barrier</FONT> -<BR>barrier.wait(); -<BR>ACE_DEBUG((LM_DEBUG,"(%t)Other threads are finished. Program exiting..\n")); -<BR>ACE_OS::sleep(2); -<BR>} - -<P> <A HREF="ex08.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_4/ex08.html b/docs/tutorials/Chap_4/ex08.html deleted file mode 100644 index 2418a93c0a8..00000000000 --- a/docs/tutorials/Chap_4/ex08.html +++ /dev/null @@ -1,72 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 8</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "Thread Management"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 8</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch_T.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> - -<P>ACE_Atomic_Op<ACE_Thread_Mutex,int> foo; - -<P>static void* -<BR>worker(void *arg){ -<BR> ACE_UNUSED_ARG(arg); -<BR> foo=5; -<BR> ACE_ASSERT (foo == 5); -<BR> -<BR> ++foo; -<BR> ACE_ASSERT (foo == 6); -<BR> -<BR> --foo; -<BR> ACE_ASSERT (foo == 5); -<BR> -<BR> foo += 10; -<BR> ACE_ASSERT (foo == 15); -<BR> -<BR> foo -= 10; -<BR> ACE_ASSERT (foo == 5); -<BR> -<BR> foo = 5L; -<BR> ACE_ASSERT (foo == 5); -<BR> return 0; -<BR>} - -<P>int main(int argc, char *argv[]){ -<BR>if(argc<2){ -<BR> ACE_DEBUG((LM_DEBUG,"Usage: <program_name> <number of threads>\n")); -<BR> ACE_OS::exit(1); -<BR> } -<BR> -<BR>int n_threads=ACE_OS::atoi(argv[1]); -<BR>ACE_DEBUG((LM_DEBUG,"Preparing to spawn %d threads\n",n_threads)); -<BR> - -<P><FONT COLOR="#FF0000">//Spawn off n_threads number of threads</FONT> -<BR>for(int i=0; i<n_threads; i++){ -<BR> if(ACE_Thread::spawn((ACE_THR_FUNC)worker,0,THR_DETACHED|THR_NEW_LWP)==-1) -<BR> ACE_DEBUG((LM_DEBUG,"Error in spawning thread\n")); -<BR> } - -<P><FONT COLOR="#FF0000">//Wait for all the other threads to let the main -thread know when it is time to exit</FONT> -<BR>while(ACE_Thread::join(NULL,NULL,NULL)==0); -<BR>ACE_DEBUG((LM_DEBUG,"(%t)Other threads are finished. Program exiting..\n")); -<BR>} - -<P> <A HREF="../Chap_5/ex01.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_5/Chap_5.zip b/docs/tutorials/Chap_5/Chap_5.zip Binary files differdeleted file mode 100644 index 5eb2b6646d0..00000000000 --- a/docs/tutorials/Chap_5/Chap_5.zip +++ /dev/null diff --git a/docs/tutorials/Chap_5/ex01.html b/docs/tutorials/Chap_5/ex01.html deleted file mode 100644 index 54bb3204b61..00000000000 --- a/docs/tutorials/Chap_5/ex01.html +++ /dev/null @@ -1,75 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 1</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Reactor" (Event -Management)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#FF0000">//Example 1</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600"><signal.h></FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Event_Handler.h"</FONT> - -<P><FONT COLOR="#FF0000">//Create our subclass to handle the signal events</FONT> -<BR><FONT COLOR="#FF0000">//that we wish to handle. Since we know that -this particular</FONT> -<BR><FONT COLOR="#FF0000">//event handler is going to be using signals -we only overload the</FONT> -<BR><FONT COLOR="#FF0000">//handle_signal method.</FONT> - -<P>class -<BR>MyEventHandler: public ACE_Event_Handler{ -<BR>int -<BR>handle_signal(int signum, siginfo_t*,ucontext_t*){ -<BR> switch(signum){ -<BR> case SIGWINCH: -<BR> ACE_DEBUG((LM_DEBUG, "You pressed SIGWINCH \n")); -<BR> break; - -<P> case SIGINT: -<BR> ACE_DEBUG((LM_DEBUG, "You pressed SIGINT \n")); -<BR> break; -<BR> } -<BR> return 0; -<BR> } -<BR>}; - -<P>int main(int argc, char *argv[]){ -<BR><FONT COLOR="#FF0000"> //instantiate the handler</FONT> -<BR> MyEventHandler *eh =new MyEventHandler; - -<P><FONT COLOR="#FF0000">//Register the handler asking to call back when -either SIGWINCH</FONT> -<BR><FONT COLOR="#FF0000">//or SIGINT signals occur. Note that in both -the cases we asked the</FONT> -<BR><FONT COLOR="#FF0000">//Reactor to call back the same Event_Handler -i.e., MyEventHandler.</FONT> -<BR><FONT COLOR="#FF0000">//This is the reason why we had to write a switch -statement in the handle_signal()</FONT> -<BR><FONT COLOR="#FF0000">//method above. Also note that the</FONT> -<BR><FONT COLOR="#FF0000">//ACE_Reactor is being used as a Singleton object -(Singleton pattern)</FONT> - -<P> ACE_Reactor::instance()->register_handler(SIGWINCH,eh); -<BR> ACE_Reactor::instance()->register_handler(SIGINT,eh); -<BR> while(1) -<BR> <FONT COLOR="#FF0000"> //Start the reactors event loop</FONT> -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P> <A HREF="ex02.html">Next Example</A> -<BR> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_5/ex02.html b/docs/tutorials/Chap_5/ex02.html deleted file mode 100644 index 89f5094b9c7..00000000000 --- a/docs/tutorials/Chap_5/ex02.html +++ /dev/null @@ -1,148 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 2</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Reactor" (Event -Management)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 2</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">PORT_NO -19998</FONT> -<BR>typedef ACE_SOCK_Acceptor Acceptor; -<BR><FONT COLOR="#FF0000">//forward declaration</FONT> -<BR>class My_Accept_Handler; - -<P>class -<BR>My_Input_Handler: public ACE_Event_Handler{ -<BR>public: -<BR><FONT COLOR="#FF0000"> //Constructor</FONT> -<BR> My_Input_Handler(){ -<BR> ACE_DEBUG((LM_DEBUG,?Constructor\n?); -<BR> } -<BR> -<BR><FONT COLOR="#FF0000"> //Called back to handle any input receieved</FONT> -<BR> int -<BR> handle_input(ACE_HANDLE){ -<BR><FONT COLOR="#FF0000"> //receive the data</FONT> -<BR> peer().recv_n(data,12); -<BR> ACE_DEBUG((LM_DEBUG,?%s\n?,data)); -<BR> -<BR> <FONT COLOR="#FF0000"> // do something with the input received.</FONT> -<BR><FONT COLOR="#FF0000"> // ...</FONT> - -<P><FONT COLOR="#FF0000"> //keep yourself registered with the reactor</FONT> -<BR> return 0; -<BR> } -<BR> -<BR><FONT COLOR="#FF0000"> //Used by the reactor to determine the -underlying handle</FONT> -<BR> ACE_HANDLE -<BR> get_handle()const { -<BR> return this->peer_i().get_handle(); -<BR> } -<BR> -<BR><FONT COLOR="#FF0000"> //Returns a reference to the underlying -stream.</FONT> -<BR> ACE_SOCK_Stream & -<BR> peer_i(){ -<BR> return this->peer_; -<BR> } - -<P>private: -<BR> ACE_SOCK_Stream peer_; -<BR> char data [12]; -<BR>}; -<BR> - -<P>class -<BR>My_Accept_Handler: public ACE_Event_Handler{ -<BR>public: -<BR><FONT COLOR="#FF0000">//Constructor</FONT> -<BR> My_Accept_Handler(ACE_Addr &addr){ -<BR> this->open(addr); -<BR> } - -<P><FONT COLOR="#FF0000">//Open the peer_acceptor so it starts to ?listen?</FONT> -<BR><FONT COLOR="#FF0000">//for incoming clients.</FONT> -<BR> int -<BR> open(ACE_Addr &addr){ -<BR> peer_acceptor.open(addr); -<BR> return 0; -<BR> } - -<P><FONT COLOR="#FF0000">//Overload the handle input method</FONT> -<BR> int -<BR> handle_input(ACE_HANDLE handle){ -<BR> <FONT COLOR="#FF0000"> //Client has requested connection to server.</FONT> -<BR><FONT COLOR="#FF0000"> //Create a handler to handle the connection</FONT> -<BR> My_Input_Handler *eh= new My_Input_Handler(); - -<P> <FONT COLOR="#FF0000">//Accept the connection ?into? the Event -Handler</FONT> -<BR> if (this->peer_acceptor.accept (eh->peer (), <FONT COLOR="#FF0000">// -stream</FONT> -<BR> 0, <FONT COLOR="#FF0000">// remote address</FONT> -<BR> 0, <FONT COLOR="#FF0000">// timeout</FONT> -<BR> 1) ==-1) <FONT COLOR="#FF0000">//restart -if interrupted</FONT> -<BR> ACE_DEBUG((LM_ERROR,"Error in connection\n")); - -<P> ACE_DEBUG((LM_DEBUG,"Connection established\n")); - -<P><FONT COLOR="#FF0000"> //Register the input event handler for -reading</FONT> -<BR> ACE_Reactor::instance()-> -<BR> register_handler(eh,ACE_Event_Handler::READ_MASK); - -<P><FONT COLOR="#FF0000"> //Unregister as the acceptor is not expecting -new clients</FONT> -<BR> return -1; -<BR> } - -<P><FONT COLOR="#FF6666"> //Used by the reactor to determine the underlying -handle</FONT> -<BR> ACE_HANDLE -<BR> get_handle(void) const{ -<BR> return this->peer_acceptor.get_handle(); -<BR> } -<BR>private: -<BR> Acceptor peer_acceptor; -<BR>}; - -<P>int main(int argc, char * argv[]){ -<BR><FONT COLOR="#FF0000"> //Create an address on which to receive -connections</FONT> -<BR> ACE_INET_Addr addr(PORT_NO); - -<P><FONT COLOR="#FF0000">//Create the Accept Handler which automatically -begins to "listen"</FONT> -<BR><FONT COLOR="#FF0000">//for client requests for connections</FONT> -<BR> My_Accept_Handler *eh=new My_Accept_Handler(addr); - -<P><FONT COLOR="#FF0000">//Register the reactor to call back when incoming -client connects</FONT> -<BR>ACE_Reactor::instance()->register_handler(eh, -<BR> ACE_Event_Handler::ACCEPT_MASK); - -<P><FONT COLOR="#FF0000">//Start the event loop</FONT> -<BR>while(1) -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P> <A HREF="ex03.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_5/ex03.html b/docs/tutorials/Chap_5/ex03.html deleted file mode 100644 index 07dabd17a97..00000000000 --- a/docs/tutorials/Chap_5/ex03.html +++ /dev/null @@ -1,86 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 3</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Reactor" (Event -Management)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#FF0000">//Example 3</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Timer_Queue.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">NUMBER_TIMERS -10</FONT> - -<P>static int done = 0; -<BR>static int count = 0; - -<P>class Time_Handler : public ACE_Event_Handler -<BR>{ -<BR>public: -<BR> <FONT COLOR="#FF0000">//Method which is called back by the Reactor -when timeout occurs.</FONT> -<BR> virtual int handle_timeout (const ACE_Time_Value &tv, -<BR> const void *arg){ -<BR> long current_count = long (arg); -<BR> ACE_ASSERT (current_count == count); -<BR> ACE_DEBUG ((LM_DEBUG, "%d: Timer #%d timed out at %d!\n", -<BR> count, current_count, tv.sec())); -<BR> - -<P><FONT COLOR="#FF0000">//Increment count</FONT> -<BR> count ++; - -<P><FONT COLOR="#FF0000">//Make sure assertion doesnt fail for missing -5th timer.</FONT> -<BR> if (count ==5) -<BR> count++; -<BR> -<BR><FONT COLOR="#FF0000"> //If all timers done then set done flag</FONT> -<BR> if (current_count == NUMBER_TIMERS - 1) -<BR> done = 1; -<BR><FONT COLOR="#FF0000"> //Keep yourself registered with the Reactor.</FONT> -<BR> return 0; -<BR> } -<BR>}; - -<P>int -<BR>main (int, char *[]) -<BR>{ -<BR> ACE_Reactor reactor; -<BR> Time_Handler *th=new Time_Handler; -<BR> int timer_id[NUMBER_TIMERS]; -<BR> int i; - -<P> for (i = 0; i < NUMBER_TIMERS; i++) -<BR> timer_id[i] = reactor.schedule_timer (th, -<BR> (const void *) i, <FONT COLOR="#FF0000">// argument sent -to handle_timeout()</FONT> -<BR> ACE_Time_Value (2 * i + 1));<FONT COLOR="#FF0000"> //set -timer to go off with delay</FONT> - -<P><FONT COLOR="#CC0000"> //Cancel the fifth timer before it goes -off</FONT> -<BR> reactor.cancel_timer(timer_id[5]);<FONT COLOR="#FF0000">//Timer -ID of timer to be removed</FONT> - -<P> while (!done) -<BR> reactor.handle_events (); - -<P> return 0; -<BR>} - -<P> <A HREF="ex04.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_5/ex04.html b/docs/tutorials/Chap_5/ex04.html deleted file mode 100644 index e0d0181d14d..00000000000 --- a/docs/tutorials/Chap_5/ex04.html +++ /dev/null @@ -1,84 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 4</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Reactor" (Event -Management)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#FF0000">//Example 4</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Event_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch_T.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Thread_Manager.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">WAIT_TIME -1</FONT> -<BR><FONT COLOR="#000099">#define</FONT><FONT COLOR="#663366"> SLEEP_TIME -2</FONT> - -<P>class My_Handler: public ACE_Event_Handler{ -<BR> public: - -<P><FONT COLOR="#FF0000"> //Start the event handling process.</FONT> -<BR> My_Handler(){ -<BR> ACE_DEBUG((LM_DEBUG,"Event Handler created\n")); -<BR> ACE_Reactor::instance()->max_notify_iterations(5); -<BR> return 0; -<BR> } - -<P><FONT COLOR="#FF0000">//Perform the notifications i.e., notify the reactor -10 times</FONT> -<BR> void perform_notifications(){ -<BR> for(int i=0;i<10;i++) -<BR> ACE_Reactor::instance()-> -<BR> notify(this,ACE_Event_Handler::READ_MASK); -<BR> } -<BR> -<BR><FONT COLOR="#FF0000"> //The actual handler which in this case -will handle the notifications</FONT> -<BR> int handle_input(int){ -<BR> ACE_DEBUG((LM_DEBUG,"Got notification # %d\n",no)); -<BR> no++; -<BR> return 0; -<BR> } -<BR>private: -<BR> static int no; -<BR>}; - -<P><FONT COLOR="#FF0000">//Static members</FONT> -<BR>int My_Handler::no=1; -<BR> - -<P>int main(int argc, char *argv[]){ -<BR><FONT COLOR="#FF0000"> //Instantiating the handler</FONT> -<BR> My_Handler handler; -<BR> -<BR><FONT COLOR="#FF0000"> //The done flag is set to not done yet.</FONT> -<BR> int done=0; - -<P>while(1){ -<BR> <FONT COLOR="#FF0000"> //After WAIT_TIME the handle_events will -fall through if no events arrive.</FONT> -<BR> ACE_Reactor::instance()->handle_events(ACE_Time_Value(WAIT_TIME)); -<BR> if(!done){ -<BR> handler.perform_notifications(); -<BR> done=1; -<BR> } -<BR> sleep(SLEEP_TIME); -<BR> } -<BR>} - -<P> <A HREF="ex05.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_5/ex05.html b/docs/tutorials/Chap_5/ex05.html deleted file mode 100644 index 665730fcace..00000000000 --- a/docs/tutorials/Chap_5/ex05.html +++ /dev/null @@ -1,87 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 5</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Reactor" (Event -Management)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 5</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Event_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch_T.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Thread_Manager.h"</FONT> - -<P>class My_Handler: public ACE_Event_Handler{ -<BR>public: -<BR><FONT COLOR="#FF0000"> //Start the event handling process.</FONT> -<BR> My_Handler(){ -<BR> ACE_DEBUG((LM_DEBUG,"Got open\n")); -<BR> activate_threads(); -<BR> ACE_Reactor::instance()->max_notify_iterations(5); -<BR> return 0; -<BR> } - -<P><FONT COLOR="#FF0000">//Spawn a separate thread so that it notifies -the reactor</FONT> -<BR> void activate_threads(){ -<BR> ACE_Thread_Manager::instance() -<BR> ->spawn((ACE_THR_FUNC)svc_start,(void*)this); -<BR> } -<BR> -<BR><FONT COLOR="#FF0000"> //Notify the Reactor 10 times.</FONT> -<BR> void svc(){ -<BR> for(int i=0;i<10;i++) -<BR> ACE_Reactor::instance() -<BR> ->notify(this, ACE_Event_Handler::READ_MASK); -<BR> } - -<P><FONT COLOR="#FF0000">//The actual handler which in this case will handle -the notifications</FONT> -<BR> int handle_input(int){ -<BR> ACE_DEBUG((LM_DEBUG, ?Got notification # %d\n?, no)); -<BR> no++; -<BR> return 0; -<BR> } - -<P> <FONT COLOR="#FF0000">//The entry point for the new thread that -is to be created.</FONT> -<BR> static int svc_start(void* arg); -<BR>private: -<BR> static int no; -<BR>}; -<BR> - -<P><FONT COLOR="#FF0000">//Static members</FONT> -<BR>int My_Handler::no=1; -<BR>int My_Handler::svc_start(void* arg){ -<BR> My_Handler *eh= (My_Handler*)arg; -<BR> eh->svc(); -<BR> return -1; <FONT COLOR="#FF0000">//de-register from the reactor</FONT> -<BR> } - -<P>int main(int argc, char *argv[]){ -<BR> ACE_DEBUG((LM_DEBUG,"Starting test \n")); -<BR> My_Handler handler; - -<P> while(1){ -<BR> ACE_Reactor::instance()->handle_events(); -<BR> sleep(3); -<BR> } -<BR>} -<BR> -<BR> -<BR> <A HREF="../Chap_6/ex01.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/Chap_6.zip b/docs/tutorials/Chap_6/Chap_6.zip Binary files differdeleted file mode 100644 index fcfd5455cba..00000000000 --- a/docs/tutorials/Chap_6/Chap_6.zip +++ /dev/null diff --git a/docs/tutorials/Chap_6/ex01.html b/docs/tutorials/Chap_6/ex01.html deleted file mode 100644 index ff60ea6dcb7..00000000000 --- a/docs/tutorials/Chap_6/ex01.html +++ /dev/null @@ -1,81 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 1</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#FF0000">//Example 1</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include </FONT><FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> - -<P><FONT COLOR="#FF0000">//Create a Service Handler whose open() method -will be called back automatically.</FONT> -<BR><FONT COLOR="#FF0000">//This class MUST derive from ACE_Svc_Handler -which is an interface and</FONT> -<BR><FONT COLOR="#FF0000">//as can be seen is a template container class -itself. The first parameter to //ACE_Svc_Handler is the underlying stream -that it may use for communication.</FONT> -<BR><FONT COLOR="#FF0000">//Since we are using TCP sockets the stream is -ACE_SOCK_STREAM.</FONT> -<BR><FONT COLOR="#FF0000">//The second is the internal synchronization -mechanism it could use.</FONT> -<BR><FONT COLOR="#FF0000">//Since we have a single threaded application -we pass it a "null" lock</FONT> -<BR><FONT COLOR="#FF0000">//which will do nothing.</FONT> - -<P>class My_Svc_Handler: -<BR> public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>{ -<BR><FONT COLOR="#FF0000">//the open method which will be called back automatically -after the</FONT> -<BR><FONT COLOR="#FF0000">//connection has been established</FONT>. - -<P>public: -<BR>int open(void*){ -<BR> cout<<?Connection established?<<endl; -<BR> } -<BR>}; -<BR><FONT COLOR="#FF0000">// Create the acceptor as described above.</FONT> -<BR>typedef ACE_Acceptor<My_Svc_Handler,ACE_SOCK_ACCEPTOR> MyAcceptor; - -<P>int main(int argc, char* argv[]){ -<BR><FONT COLOR="#FF0000">//create the address on which we wish to -connect. The constructor takes</FONT> -<BR><FONT COLOR="#FF0000">//the port number on which to listen and will -automatically take the hosts</FONT> -<BR><FONT COLOR="#FF0000">//IP address as the IP Address for the addr object</FONT> - -<P>ACE_INET_Addr addr(PORT_NUM); - -<P><FONT COLOR="#FF0000">//instantiate the appropriate acceptor object -with the address on which we wish to</FONT> -<BR><FONT COLOR="#FF0000">//accept and the Reactor instance we want to -use. In this case we just use the global</FONT> -<BR><FONT COLOR="#FF0000">//ACE_Reactor singleton. (Read more about the -reactor in the previous chapter)</FONT> -<BR>MyAcceptor acceptor(address, ACE_Reactor::instance()); - -<P>while(1) -<BR><FONT COLOR="#FF0000"> // Start the reactors event loop</FONT> -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P> <A HREF="ex02.html">Next Example</A> -<BR> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex02.html b/docs/tutorials/Chap_6/ex02.html deleted file mode 100644 index a5ab4cca339..00000000000 --- a/docs/tutorials/Chap_6/ex02.html +++ /dev/null @@ -1,94 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 2</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 2</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">PORT_NUM -10101</FONT> -<BR><FONT COLOR="#000099">#define</FONT><FONT COLOR="#663366"> DATA_SIZE -12</FONT> - -<P><FONT COLOR="#FF0000">//forward declaration</FONT> -<BR>class My_Svc_Handler; - -<P><FONT COLOR="#FF0000">//Create the Acceptor class</FONT> -<BR>typedef ACE_Acceptor<My_Svc_Handler,ACE_SOCK_ACCEPTOR> MyAcceptor; - -<P><FONT COLOR="#FF0000">//Create a service handler similar to as seen -in example 1.</FONT> -<BR><FONT COLOR="#FF0000">//Except this time include the handle_input() -method which will be</FONT> -<BR><FONT COLOR="#FF0000">//called back automatically by the reactor when -new data arrives</FONT> -<BR><FONT COLOR="#FF0000">//on the newly established connection</FONT> -<BR>class My_Svc_Handler: -<BR> public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>{ -<BR>public: -<BR>My_Svc_Handler(){ -<BR> data= new char[DATA_SIZE]; -<BR> } -<BR>int open(void*){ -<BR> ACE_DEBUG((LM_DEBUG,"Connection established")); - -<P><FONT COLOR="#FF0000"> //Register the service handler with the -reactor</FONT> -<BR> ACE_Reactor::instance()->register_handler(this, -<BR> ACE_Event_Handler::READ_MASK); -<BR> return 0; -<BR> } - -<P>int handle_input(ACE_HANDLE){ -<BR> <FONT COLOR="#FF0000">//After using the peer() method of ACE_Svc_Handler -to obtain a</FONT> -<BR><FONT COLOR="#FF0000">//reference to the underlying stream of the service -handler class</FONT> -<BR><FONT COLOR="#FF0000">//we call recv_n() on it to read the data which -has been received.</FONT> -<BR><FONT COLOR="#FF0000">//This data is stored in the data array and then -printed out</FONT> -<BR> peer().recv_n(data,DATA_SIZE); -<BR> ACE_OS::printf("<< %s\n",data); - -<P> <FONT COLOR="#FF0000">//keep yourself registered with the reactor</FONT> -<BR> return 0; -<BR> } -<BR>private: -<BR> char* data; -<BR>}; - -<P>int main(int argc, char* argv[]){ -<BR> ACE_INET_Addr addr(PORT_NUM); -<BR><FONT COLOR="#FF0000"> //create the acceptor</FONT> -<BR> MyAcceptor acceptor(addr, <FONT COLOR="#FF0000">//address to -accept on</FONT> -<BR> ACE_Reactor::instance()); <FONT COLOR="#FF0000">//the reactor -to use</FONT> - -<P>while(1) -<BR><FONT COLOR="#FF0000"> //Start the reactor?s event loop</FONT> -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P> <A HREF="ex03.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex03.html b/docs/tutorials/Chap_6/ex03.html deleted file mode 100644 index a68bd303b61..00000000000 --- a/docs/tutorials/Chap_6/ex03.html +++ /dev/null @@ -1,50 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 3</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example3</FONT> - -<P>class My_Svc_Handler: -<BR>public ACE_Svc_Handler <ACE_LSOCK_STREAM,ACE_NULL_SYNCH>{ -<BR>public: -<BR>int open(void*){ -<BR> ACE_DEBUG((LM_DEBUG,"Connection established")); -<BR> ACE_Reactor::instance() ->register_handler(this,ACE_Event_Handler::READ_MASK); -<BR> } - -<P> int handle_input(ACE_HANDLE){ -<BR> char* data= new char[DATA_SIZE]; -<BR> peer().recv_n(data,DATA_SIZE); -<BR> ACE_OS::printf("<< %s\n",data); -<BR> return 0; -<BR> } -<BR>}; - -<P>typedef ACE_Acceptor<My_Svc_Handler,ACE_LSOCK_ACCEPTOR> MyAcceptor; - -<P>int main(int argc, char* argv[]){ -<BR> ACE_UNIX_Addr addr("/tmp/addr.ace"); -<BR> MyAcceptor acceptor(address, ACE_Reactor::instance()); - -<P>while(1) <FONT COLOR="#FF0000">/* Start the reactors event loop */</FONT> -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P> <A HREF="ex04.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex04.html b/docs/tutorials/Chap_6/ex04.html deleted file mode 100644 index f5910341621..00000000000 --- a/docs/tutorials/Chap_6/ex04.html +++ /dev/null @@ -1,44 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 4</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 4 (Use in conjunction with other examples -to create running example)</FONT><FONT COLOR="#CC0000"></FONT> - -<P>typedef ACE_Connector<My_Svc_Handler,ACE_SOCK_CONNECTOR> MyConnector; - -<P>int main(int argc, char * argv[]){ -<BR> ACE_INET_Addr addr(PORT_NO,HOSTNAME); -<BR> My_Svc_Handler * handler= new My_Svc_Handler; - -<P><FONT COLOR="#FF0000">//Create the connector</FONT> -<BR> MyConnector connector; - -<P><FONT COLOR="#FF0000">//Connects to remote machine</FONT> -<BR> if(connector.connect(handler,addr)==-1) -<BR> ACE_ERROR(LM_ERROR,?%P|%t, %p?,?Connection failed?); -<BR> - -<P><FONT COLOR="#FF0000">//Registers with the Reactor</FONT> -<BR> while(1) -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P> <A HREF="ex05.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex05.html b/docs/tutorials/Chap_6/ex05.html deleted file mode 100644 index c983e5751f9..00000000000 --- a/docs/tutorials/Chap_6/ex05.html +++ /dev/null @@ -1,129 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 5</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 5</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Thread.h"</FONT> - -<P><FONT COLOR="#FF0000">//Add our own Reactor singleton</FONT> -<BR>typedef ACE_Singleton<ACE_Reactor,ACE_Null_Mutex> Reactor; -<BR><FONT COLOR="#FF0000">//Create an Acceptor</FONT> -<BR>typedef ACE_Acceptor<MyServiceHandler,ACE_SOCK_ACCEPTOR> Acceptor; -<BR><FONT COLOR="#FF0000">//Create a Connector</FONT> -<BR>typedef ACE_Connector<MyServiceHandler,ACE_SOCK_CONNECTOR> Connector; - -<P>class MyServiceHandler: -<BR>public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH>{ -<BR>public: -<BR><FONT COLOR="#FF0000"> //Used by the two threads "globally" to -determine their peer stream</FONT> -<BR> static ACE_SOCK_Stream* Peer; - -<P><FONT COLOR="#FF0000">//Thread ID used to identify the threads</FONT> -<BR> ACE_thread_t t_id; - -<P>int open(void*){ -<BR> ACE_DEBUG((LM_DEBUG,"Acceptor: received new connection\n")); - -<P><FONT COLOR="#FF0000">//Register with the reactor to remember this handlle</FONT> -<BR> Reactor::instance() ->register_handler(this,ACE_Event_Handler::READ_MASK); - -<P><FONT COLOR="#FF0000">//Determine the peer stream and record it globally</FONT> -<BR> MyServiceHandler::Peer=&peer(); -<BR> -<BR> <FONT COLOR="#FF0000">//Spawn new thread to send string every -second</FONT> -<BR> ACE_Thread::spawn((ACE_THR_FUNC)send_data,0,THR_NEW_LWP,&t_id); -<BR> -<BR> <FONT COLOR="#FF0000"> //keep the service handler registered -by returning 0 to the reactor</FONT> -<BR> return 0; -<BR> } -<BR> - -<P>static void* send_data(void*){ -<BR> while(1){ -<BR> ACE_DEBUG((LM_DEBUG,"Hello World\n")); -<BR> Peer->send_n("Hello World",sizeof("Hello World")); -<BR> -<BR> <FONT COLOR="#FF0000">//Go to sleep for a second before -sending again</FONT> -<BR> ACE_OS::sleep(1); -<BR> } -<BR> return 0; -<BR> } -<BR> - -<P>int handle_input(ACE_HANDLE){ -<BR> char* data= new char[12]; -<BR> -<BR> <FONT COLOR="#FF0000"> //Check if peer aborted the connection</FONT> -<BR> if(Peer.recv_n(data,12)==0){ -<BR> ACE_DEBUG((LM_DEBUG,"Peer probably aborted connection\n")); -<BR> ACE_Thread::cancel(t_id); <FONT COLOR="#CC0000">//kill -sending thread ..</FONT> -<BR> return -1; <FONT COLOR="#FF0000">//de-register from the -Reactor.</FONT> -<BR> } - -<P> <FONT COLOR="#FF0000"> //Show what you got..</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"<< %s\n",data)); -<BR> -<BR> <FONT COLOR="#FF0000">//keep yourself registered</FONT> -<BR> return 0; -<BR> } -<BR>}; - -<P><FONT COLOR="#FF0000">//Global stream identifier used by both threads</FONT> -<BR>ACE_SOCK_Stream * MyServiceHandler::Peer=0; -<BR> - -<P>void main_accept(){ -<BR> ACE_INET_Addr addr(PORT_NO); -<BR> Acceptor myacceptor(addr,Reactor::instance()); -<BR> while(1) -<BR> Reactor::instance()->handle_events(); - -<P> return 0; -<BR> } - -<P>void main_connect(){ -<BR> ACE_INET_Addr addr(PORT_NO,HOSTNAME); -<BR> Connector myconnector; -<BR> myconnector.connect(my_svc_handler,addr); -<BR> while(1) -<BR> Reactor::instance()->handle_events(); - -<P> } -<BR> - -<P>int main(int argc, char* argv[]){ -<BR><FONT COLOR="#FF0000"> // Use ACE_Get_Opt to parse and obtain -arguments and then call the</FONT> -<BR> <FONT COLOR="#FF0000">// approriate function for accept or connect.</FONT> -<BR><FONT COLOR="#CC0000">//...</FONT> -<BR>} -<BR> -<BR> <A HREF="ex06.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex06.html b/docs/tutorials/Chap_6/ex06.html deleted file mode 100644 index 7bfc3b91beb..00000000000 --- a/docs/tutorials/Chap_6/ex06.html +++ /dev/null @@ -1,134 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 6</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 6</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> - -<P>class MyServiceHandler; //forward declaration -<BR>typedef ACE_Singleton<ACE_Reactor,ACE_Null_Mutex> Reactor; -<BR>typedef ACE_Acceptor<MyServiceHandler,ACE_SOCK_ACCEPTOR> Acceptor; - -<P>class MyServiceHandler: -<BR>public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_MT_SYNCH>{ -<BR><FONT COLOR="#FF0000">// The two thread names are kept here</FONT> -<BR>ACE_thread_t thread_names[2]; - -<P>public: -<BR>int open(void*){ -<BR> ACE_DEBUG((LM_DEBUG, "Acceptor: received new connection \n")); -<BR> -<BR> <FONT COLOR="#FF0000">//Register with the reactor to remember -this handler..</FONT> -<BR> Reactor::instance() ->register_handler(this,ACE_Event_Handler::READ_MASK); -<BR> ACE_DEBUG((LM_DEBUG,"Acceptor: ThreadID:(%t) open\n")); - -<P><FONT COLOR="#CC0000"> //Create two new threads to create and send -messages to the remote machine.</FONT> -<BR> activate(THR_NEW_LWP, -<BR> 2, <FONT COLOR="#FF0000">//2 new threads</FONT> -<BR> 0, <FONT COLOR="#FF0000">//force active false, if already -created dont try again.</FONT> -<BR> ACE_DEFAULT_THREAD_PRIORITY,<FONT COLOR="#FF0000">//Use -default thread priority</FONT> -<BR> -1, -<BR> this,<FONT COLOR="#FF0000">//Which ACE_Task object to -create? In this case this one.</FONT> -<BR> 0,<FONT COLOR="#FF0000">// dont care about thread handles -used</FONT> -<BR> 0,<FONT COLOR="#FF0000">// dont care about where stacks -are created</FONT> -<BR> 0,<FONT COLOR="#FF0000">//dont care about stack sizes</FONT> -<BR> thread_names); <FONT COLOR="#FF0000">// keep identifiers -in thread_names</FONT> -<BR> -<BR><FONT COLOR="#FF0000"> //keep the service handler registered with -the acceptor.</FONT> -<BR> return 0; -<BR> } - -<P>void send_message1(void){ -<BR> <FONT COLOR="#FF0000">//Send message type 1</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"(%t)Sending message >>")); - -<P> <FONT COLOR="#FF0000">//Send the data to the remote peer</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"Sent message1")); -<BR> peer().send_n("Message1",LENGTH_MSG_1); -<BR> } <FONT COLOR="#FF0000">//end send_message1</FONT> - -<P>int send_message2(void){ -<BR> <FONT COLOR="#FF0000">//Send message type 1</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"(%t)Sending message >>")); - -<P> <FONT COLOR="#FF0000">//Send the data to the remote peer</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"Sent Message2")); -<BR> peer().send_n("Message2",LENGTH_MSG_2); -<BR> }<FONT COLOR="#FF0000">//end send_message_2</FONT> -<BR> -<BR>int svc(void){ -<BR> ACE_DEBUG( (LM_DEBUG,?(%t) Svc thread \n?)); -<BR> -<BR> if(ACE_Thread::self()== thread_names[0]) -<BR> while(1) send_message1(); <FONT COLOR="#FF0000">//send message -1s forever</FONT> -<BR> else -<BR> while(1) send_message2(); <FONT COLOR="#FF0000">//send message -2s forever</FONT> -<BR> return 0; <FONT COLOR="#FF0000">// keep the compiler happy.</FONT> -<BR>} -<BR> -<BR>int handle_input(ACE_HANDLE){ -<BR> ACE_DEBUG((LM_DEBUG,?(%t) handle_input ::?)); -<BR> char* data= new char[13]; -<BR> -<BR> <FONT COLOR="#FF0000">//Check if peer aborted the connection</FONT> -<BR> if(peer().recv_n(data,12)==0){ -<BR> ACE_OS::printf("Peer probably aborted connection\n"); -<BR> return -1; <FONT COLOR="#FF0000">//de-register from the Reactor.</FONT> -<BR> } -<BR> -<BR> <FONT COLOR="#FF0000">//Show what you got..</FONT> -<BR> ACE_OS::printf("<< %s\n",data); -<BR> -<BR> <FONT COLOR="#FF0000">//keep yourself registered</FONT> -<BR> return 0; -<BR> -<BR> } -<BR>}; - -<P>int main(int argc, char* argv[]){ -<BR> ACE_INET_Addr addr(10101); -<BR> ACE_DEBUG((LM_DEBUG,"Thread: (%t) main\n")); - -<P> <FONT COLOR="#FF0000">//Prepare to accept connections</FONT> -<BR> Acceptor myacceptor(addr,Reactor::instance()); - -<P><FONT COLOR="#FF0000"> // wait for something to happen.</FONT> -<BR> while(1) -<BR> Reactor::instance()->handle_events(); -<BR> -<BR> return 0; -<BR>} - -<P> <A HREF="ex07.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex07.html b/docs/tutorials/Chap_6/ex07.html deleted file mode 100644 index 7ecf0e57bb3..00000000000 --- a/docs/tutorials/Chap_6/ex07.html +++ /dev/null @@ -1,173 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 7</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 7</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include </FONT><FONT COLOR="#006600">"ace/Thread.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">NETWORK_SPEED -3</FONT> -<BR>class MyServiceHandler;<FONT COLOR="#FF0000"> //forward declaration</FONT> -<BR>typedef ACE_Singleton<ACE_Reactor,ACE_Null_Mutex> Reactor; -<BR>typedef ACE_Acceptor<MyServiceHandler,ACE_SOCK_ACCEPTOR> Acceptor; - -<P>class MyServiceHandler: -<BR>public ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_MT_SYNCH>{ -<BR><FONT COLOR="#FF0000">// The message sender and creator threads are -handled here.</FONT> -<BR>ACE_thread_t thread_names[2]; - -<P>public: -<BR>int open(void*){ -<BR> ACE_DEBUG((LM_DEBUG, "Acceptor: received new connection \n")); - -<P><FONT COLOR="#FF0000"> //Register with the reactor to remember -this handler..</FONT> -<BR> Reactor::instance() ->register_handler(this,ACE_Event_Handler::READ_MASK); -<BR> ACE_DEBUG((LM_DEBUG,"Acceptor: ThreadID:(%t) open\n")); - -<P><FONT COLOR="#CC0000"> //Create two new threads to create and send -messages to the</FONT> -<BR><FONT COLOR="#CC0000"> //remote machine.</FONT> -<BR> activate(THR_NEW_LWP, -<BR> 2, <FONT COLOR="#FF0000">//2 new threads</FONT> -<BR> 0, -<BR> ACE_DEFAULT_THREAD_PRIORITY, -<BR> -1, -<BR> this, -<BR> 0, -<BR> 0, -<BR> 0, -<BR> thread_names); <FONT COLOR="#FF0000">// identifiers in -thread_handles</FONT> -<BR> -<BR> <FONT COLOR="#FF0000">//keep the service handler registered with -the acceptor.</FONT> -<BR> return 0; -<BR> } - -<P>void send_message(void){ -<BR><FONT COLOR="#FF0000"> //Dequeue the message and send it off</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"(%t)Sending message >>")); - -<P><FONT COLOR="#FF0000"> //dequeue the message from the message queue</FONT> -<BR> ACE_Message_Block *mb; -<BR> ACE_ASSERT(this->getq(mb)!=-1); -<BR> int length=mb->length(); -<BR> char *data =mb->rd_ptr(); - -<P> -<BR><FONT COLOR="#FF0000"> //Send the data to the remote peer</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"%s \n",data,length)); -<BR> peer().send_n(data,length); - -<P> <FONT COLOR="#FF0000">//Simulate very SLOW network.</FONT> -<BR> ACE_OS::sleep(NETWORK_SPEED); - -<P><FONT COLOR="#FF0000"> //release the message block</FONT> -<BR> mb->release(); -<BR> } <FONT COLOR="#FF0000">//end send_message</FONT> - -<P>int construct_message(void){ -<BR><FONT COLOR="#FF0000"> // A very fast message creation algorithm</FONT> -<BR><FONT COLOR="#FF0000"> // would lead to the need for queuing messages..</FONT> -<BR><FONT COLOR="#FF0000"> // here. These messages are created and -then sent</FONT> -<BR><FONT COLOR="#FF0000"> // using the SLOW send_message() routine -which is</FONT> -<BR><FONT COLOR="#FF0000"> // running in a different thread so that -the message</FONT> -<BR><FONT COLOR="#FF0000"> //construction thread isn?t blocked.</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"(%t)Constructing message >> ")); - -<P> <FONT COLOR="#FF0000">// Create a new message to send</FONT> -<BR> ACE_Message_Block *mb; -<BR> char *data="Hello Connector"; -<BR> ACE_NEW_RETURN (mb,ACE_Message_Block (16,<FONT COLOR="#FF0000">//Message -16 bytes long</FONT> -<BR> ACE_Message_Block::MB_DATA,<FONT COLOR="#FF0000">//Set -header to data</FONT> -<BR> 0,<FONT COLOR="#FF0000">//No continuations</FONT>. -<BR> data<FONT COLOR="#FF0000">//The data we want to send</FONT> -<BR> ), 0); -<BR> mb->wr_ptr(16); <FONT COLOR="#FF0000">//Set the write pointer.</FONT> -<BR> -<BR> <FONT COLOR="#FF0000">// Enqueue the message into the message -queue</FONT> -<BR><FONT COLOR="#FF0000"> // we COULD have done a timed wait for -enqueuing in case</FONT> -<BR><FONT COLOR="#FF0000"> // someone else holds the lock to the queue -so it doesn?t block</FONT> -<BR><FONT COLOR="#FF0000"> //forever..</FONT> -<BR> ACE_ASSERT(this->putq(mb)!=-1); -<BR> ACE_DEBUG((LM_DEBUG,"Enqueued msg successfully\n")); -<BR>} -<BR> -<BR>int svc(void){ -<BR> ACE_DEBUG( (LM_DEBUG,?(%t) Svc thread \n?)); -<BR> -<BR><FONT COLOR="#FF0000"> //call the message creator thread</FONT> -<BR> if(ACE_Thread::self()== thread_names[0]) -<BR> while(1) construct_message(); <FONT COLOR="#FF0000">//create -messages forever</FONT> -<BR> else -<BR> while(1) send_message(); <FONT COLOR="#FF0000">//send messages -forever</FONT> -<BR> return 0; <FONT COLOR="#FF0000">// keep the compiler happy.</FONT> -<BR>} -<BR> -<BR>int handle_input(ACE_HANDLE){ -<BR> ACE_DEBUG((LM_DEBUG,"(%t) handle_input ")); -<BR> char* data= new char[13]; -<BR> -<BR> <FONT COLOR="#FF0000">//Check if peer aborted the connection</FONT> -<BR> if(peer().recv_n(data,12)==0){ -<BR> ACE_OS::printf("Peer probably aborted connection"); -<BR> return -1; <FONT COLOR="#FF0000">//de-register from the Reactor.</FONT> -<BR> } -<BR> -<BR><FONT COLOR="#FF0000"> //Show what you got..</FONT> -<BR> ACE_OS::printf("<< %s\n",data); -<BR> -<BR><FONT COLOR="#FF0000"> //keep yourself registered</FONT> -<BR> return 0; -<BR> -<BR> } -<BR>}; - -<P>int main(int argc, char* argv[]){ -<BR> ACE_INET_Addr addr(10101); -<BR> ACE_DEBUG((LM_DEBUG,"Thread: (%t) main\n")); - -<P> <FONT COLOR="#FF0000">//Prepare to accept connections</FONT> -<BR> Acceptor myacceptor(addr,Reactor::instance()); - -<P><FONT COLOR="#FF0000"> // wait for something to happen.</FONT> -<BR> while(1) -<BR> Reactor::instance()->handle_events(); -<BR> -<BR> return 0; -<BR>} - -<P> <A HREF="ex08.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex08.html b/docs/tutorials/Chap_6/ex08.html deleted file mode 100644 index d90c00fbd67..00000000000 --- a/docs/tutorials/Chap_6/ex08.html +++ /dev/null @@ -1,96 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 8</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 8</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT><FONT COLOR="#663366"> PORT_NUM -10101</FONT> -<BR><FONT COLOR="#000099">#define</FONT><FONT COLOR="#663366"> DATA_SIZE -12</FONT><FONT COLOR="#FF0000"></FONT> - -<P><FONT COLOR="#FF0000">//forward declaration</FONT> -<BR>class My_Svc_Handler;<FONT COLOR="#FF0000"></FONT> - -<P><FONT COLOR="#FF0000">//instantiate a strategy acceptor</FONT> -<BR>typedef ACE_Strategy_Acceptor<My_Svc_Handler,ACE_SOCK_ACCEPTOR> -MyAcceptor;<FONT COLOR="#FF0000"></FONT> - -<P><FONT COLOR="#FF0000">//instantiate a concurrency strategy</FONT> -<BR>typedef ACE_Process_Strategy<My_Svc_Handler> Concurrency_Strategy; - -<P><FONT COLOR="#FF0000">// Define the Service Handler</FONT> -<BR>class My_Svc_Handler: -<BR> public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>{ -<BR>private: -<BR> char* data; -<BR>public: -<BR> My_Svc_Handler(){ -<BR> data= new char[DATA_SIZE]; -<BR> } -<BR> My_Svc_Handler(ACE_Thread_Manager* tm){ -<BR> data= new char[DATA_SIZE]; -<BR> } -<BR> int open(void*){ -<BR> ACE_DEBUG((LM_DEBUG,"Connection -established\n")); -<BR><FONT COLOR="#FF0000"> -//Register with the reactor</FONT> -<BR> ACE_Reactor::instance()->register_handler(this, -<BR> ACE_Event_Handler::READ_MASK); -<BR> return 0; -<BR> } - -<P> int handle_input(ACE_HANDLE){ -<BR> peer().recv_n(data,DATA_SIZE); -<BR> ACE_OS::printf(?<< %s\n?,data); -<BR> -<BR><FONT COLOR="#FF0000"> // keep yourself registered -with the reactor</FONT> -<BR> return 0; -<BR> } -<BR>}; - -<P>int main(int argc, char* argv[]){ -<BR> ACE_INET_Addr addr(PORT_NUM); - -<P> <FONT COLOR="#FF0000">//Concurrency Strategy</FONT> -<BR> Concurrency_Strategy my_con_strat; - -<P><FONT COLOR="#FF0000">//Instantiate the acceptor</FONT> -<BR> MyAcceptor acceptor(addr, <FONT COLOR="#FF0000">//address to -accept on</FONT> -<BR> ACE_Reactor::instance(), <FONT COLOR="#FF0000">//the reactor -to use</FONT> -<BR> 0, <FONT COLOR="#FF0000">// dont care about creation strategy</FONT> -<BR> 0, <FONT COLOR="#FF0000">// dont care about connection estb. -strategy</FONT> -<BR> &my_con_strat);<FONT COLOR="#FF0000"> // use our new process -concurrency strategy</FONT> - -<P>while(1)<FONT COLOR="#FF0000"> // Start the reactors event loop</FONT> -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P> <A HREF="ex09.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex09.html b/docs/tutorials/Chap_6/ex09.html deleted file mode 100644 index e641da20bc5..00000000000 --- a/docs/tutorials/Chap_6/ex09.html +++ /dev/null @@ -1,211 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 9</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 9</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#663366"> </FONT><FONT COLOR="#006600">"ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Connector.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Connector.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/INET_Addr.h"</FONT> - -<P><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">PORT_NUM -10101</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">DATA_SIZE -16</FONT> - -<P><FONT COLOR="#FF0000">//forward declaration</FONT> -<BR>class My_Svc_Handler; -<BR><FONT COLOR="#FF0000">//Function prototype</FONT> -<BR>static void make_connections(void *arg); - -<P><FONT COLOR="#FF0000">// Template specializations for the hashing function -for the</FONT> -<BR><FONT COLOR="#FF0000">// hash_map which is used by the cache. The cache -is used internally by the</FONT> -<BR><FONT COLOR="#FF0000">// Cached Connection Strategy . Here we use ACE_Hash_Addr</FONT> -<BR><FONT COLOR="#FF0000">// as our external identifier. This utility class -has already</FONT> -<BR><FONT COLOR="#FF0000">// overloaded the == operator and the hash() -method. (The</FONT> -<BR><FONT COLOR="#FF0000">// hashing function). The hash() method delgates -the work to</FONT> -<BR><FONT COLOR="#FF0000">// hash_i() and we use the IP address and port -to get a</FONT> -<BR><FONT COLOR="#FF0000">// a unique integer hash value.</FONT> -<BR>size_t -<BR>ACE_Hash_Addr<ACE_INET_Addr>::hash_i (const ACE_INET_Addr &addr) -const -<BR>{ -<BR> return addr.get_ip_address () + addr.get_port_number (); -<BR>} - -<P><FONT COLOR="#FF0000">//instantiate a strategy acceptor</FONT> -<BR>typedef ACE_Strategy_Connector<My_Svc_Handler,ACE_SOCK_CONNECTOR> -<BR>STRATEGY_CONNECTOR; - -<P><FONT COLOR="#FF0000">//Instantiate the Creation Strategy</FONT> -<BR>typedef ACE_NOOP_Creation_Strategy<My_Svc_Handler> -<BR> NULL_CREATION_STRATEGY; -<BR><FONT COLOR="#FF0000">//Instantiate the Concurrency Strategy</FONT> -<BR>typedef ACE_NOOP_Concurrency_Strategy<My_Svc_Handler> -<BR> NULL_CONCURRENCY_STRATEGY; -<BR><FONT COLOR="#FF0000">//Instantiate the Connection Strategy</FONT> -<BR>typedef ACE_Cached_Connect_Strategy<My_Svc_Handler, -<BR> -ACE_SOCK_CONNECTOR, -<BR> -ACE_SYNCH_RW_MUTEX> -<BR> CACHED_CONNECT_STRATEGY; -<BR> -<BR>class My_Svc_Handler: -<BR>public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_MT_SYNCH>{ -<BR>private: -<BR>char* data; - -<P>public: -<BR>My_Svc_Handler(){ -<BR>data= new char[DATA_SIZE]; -<BR> } -<BR>My_Svc_Handler(ACE_Thread_Manager* tm){ -<BR>data= new char[DATA_SIZE]; -<BR> } -<BR><FONT COLOR="#FF0000">//Called before the service handler is recycled..</FONT> -<BR>int -<BR>recycle (void *a=0){ -<BR> ACE_DEBUG ((LM_DEBUG, -<BR> "(%P|%t) recycling Svc_Handler %d with handle %d\n", -<BR> -this, this->peer ().get_handle ())); -<BR> return 0; -<BR> } - -<P>int open(void*){ -<BR> ACE_DEBUG((LM_DEBUG,"(%t)Connection established \n")); -<BR> -<BR> -<BR> - -<P><FONT COLOR="#FF0000"> //Register the service handler with the -reactor</FONT> -<BR> ACE_Reactor::instance() ->register_handler(this,ACE_Event_Handler::READ_MASK); -<BR> activate(THR_NEW_LWP|THR_DETACHED); -<BR> return 0; -<BR> } - -<P>int handle_input(ACE_HANDLE){ -<BR> ACE_DEBUG((LM_DEBUG,"Got input in thread: (%t) \n")); -<BR> peer().recv_n(data,DATA_SIZE); -<BR> ACE_DEBUG((LM_DEBUG,"<< %s\n",data)); - -<P> <FONT COLOR="#FF0000">//keep yourself registered with the reactor</FONT> -<BR> return 0; -<BR>} - -<P>int svc(void){ -<BR><FONT COLOR="#FF0000"> //send a few messages and then mark connection -as idle so that it can be recycled later.</FONT> -<BR> ACE_DEBUG((LM_DEBUG,"Started the service routine \n")); - -<P> for(int i=0;i<3;i++){ -<BR> ACE_DEBUG((LM_DEBUG,"(%t)>>Hello World\n")); -<BR> ACE_OS::fflush(stdout); -<BR> peer().send_n("Hello World",sizeof("Hello World")); -<BR> } - -<P> <FONT COLOR="#FF0000">//Mark the service handler as being idle -now and let the other threads reuse this connection</FONT> -<BR> this->idle(1); - -<P> <FONT COLOR="#FF0000">//Wait for the thread to die</FONT> -<BR> this->thr_mgr()->wait(); -<BR> return 0; -<BR> } -<BR>}; -<BR>ACE_INET_Addr *addr; - -<P>int main(int argc, char* argv[]){ -<BR> addr= new ACE_INET_Addr(PORT_NUM,argv[1]); -<BR><FONT COLOR="#FF0000"> //Creation Strategy</FONT> -<BR> NULL_CREATION_STRATEGY creation_strategy; - -<P><FONT COLOR="#FF0000"> //Concurrency Strategy</FONT> -<BR> NULL_CONCURRENCY_STRATEGY concurrency_strategy; - -<P><FONT COLOR="#FF0000"> //Connection Strategy</FONT> -<BR> CACHED_CONNECT_STRATEGY caching_connect_strategy; -<BR> - -<P><FONT COLOR="#FF0000"> //instantiate the connector</FONT> -<BR> STRATEGY_CONNECTOR connector( -<BR> ACE_Reactor::instance(),<FONT COLOR="#FF0000"> //the reactor -to use</FONT> -<BR> &creation_strategy, -<BR> &caching_connect_strategy, -<BR> &concurrency_strategy); -<BR><FONT COLOR="#FF0000"> //Use the thread manager to spawn -a single thread to</FONT> -<BR><FONT COLOR="#FF0000"> //connect multiple times passing it the -address</FONT> -<BR><FONT COLOR="#FF0000"> //of the strategy connector</FONT> -<BR> if(ACE_Thread_Manager::instance()->spawn( -<BR> (ACE_THR_FUNC) make_connections, -<BR> (void *) &connector, -<BR> THR_NEW_LWP) == -1) -<BR> ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n%a", "client thread spawn -failed")); - -<P>while(1) /* Start the reactor?s event loop */ -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} - -<P><FONT COLOR="#FF0000">//Connection establishment function, tries to -establish connections</FONT> -<BR><FONT COLOR="#FF0000">//to the same server again and re-uses the connections -from the</FONT> -<BR><FONT COLOR="#FF0000">//cache</FONT> -<BR>void make_connections(void *arg){ -<BR> ACE_DEBUG((LM_DEBUG,"(%t)Prepared to connect \n")); -<BR> STRATEGY_CONNECTOR *connector= (STRATEGY_CONNECTOR*) arg; -<BR> for (int i = 0; i < 10; i++){ -<BR> My_Svc_Handler *svc_handler = 0; -<BR> - -<P> <FONT COLOR="#FF0000">// Perform a blocking connect to the server -using the Strategy</FONT> -<BR><FONT COLOR="#FF0000"> // Connector with a connection caching -strategy. Since we are</FONT> -<BR><FONT COLOR="#FF0000"> // connecting to the same <server_addr> -these calls will return the</FONT> -<BR><FONT COLOR="#FF0000"> // same dynamically allocated <Svc_Handler> -for each <connect> call.</FONT> -<BR> if (connector->connect (svc_handler, *addr) == -1){ -<BR> ACE_ERROR ((LM_ERROR, "(%P|%t) %p\n", "connection failed\n")); -<BR> return; -<BR> } - -<P><FONT COLOR="#FF0000"> // Rest for a few seconds so that the connection -has been freed up</FONT> -<BR> ACE_OS::sleep (5); -<BR> } -<BR>} -<BR> -<BR> <A HREF="ex10.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_6/ex10.html b/docs/tutorials/Chap_6/ex10.html deleted file mode 100644 index 872c1c44a82..00000000000 --- a/docs/tutorials/Chap_6/ex10.html +++ /dev/null @@ -1,110 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 10</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Acceptor/Connector" -(Connection Initialization)</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 10</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Reactor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Svc_Handler.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Synch.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/SOCK_Acceptor.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">PORT_NUM -10101</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">DATA_SIZE -12</FONT> - -<P><FONT COLOR="#FF0000">//forward declaration</FONT> -<BR>class My_Svc_Handler; - -<P><FONT COLOR="#FF0000">//Create the Acceptor class</FONT> -<BR>typedef ACE_Acceptor<My_Event_Handler,ACE_SOCK_ACCEPTOR> -<BR>MyAcceptor; - -<P><FONT COLOR="#FF0000">//Create an event handler similar to as seen in -example 2.</FONT> -<BR><FONT COLOR="#FF0000">//We have to overload the get_handle() method -and write the peer()</FONT> -<BR><FONT COLOR="#FF0000">//method. We also provide the data member peer_ -as the underlying</FONT> -<BR><FONT COLOR="#FF0000">//stream which is used.</FONT> -<BR>class My_Event_Handler: -<BR> public ACE_Event_Handler{ -<BR>private: -<BR>char* data; -<BR><FONT COLOR="#FF0000">//Add a new attribute for the underlying stream -which will be used by the Event Handler</FONT> -<BR>ACE_SOCK_Stream peer_; -<BR>public: -<BR>My_Event_Handler(){ -<BR> data= new char[DATA_SIZE]; -<BR> } - -<P>int -<BR>open(void*){ -<BR> ACE_DEBUG((LM_DEBUG,"Connection established\n")); -<BR><FONT COLOR="#FF0000"> //Register the event handler with the reactor</FONT> -<BR> ACE_Reactor::instance()->register_handler(this, ACE_Event_Handler::READ_MASK); -<BR> return 0; -<BR> } - -<P>int -<BR>handle_input(ACE_HANDLE){ -<BR> <FONT COLOR="#FF0000">// After using the peer() method of our -ACE_Event_Handler to obtain a</FONT> -<BR><FONT COLOR="#FF0000"> //reference to the underlying stream of -the service handler class we</FONT> -<BR><FONT COLOR="#FF0000"> //call recv_n() on it to read the data -which has been received. This</FONT> -<BR><FONT COLOR="#FF0000"> //data is stored in the data array and -then printed out</FONT> -<BR> peer().recv_n(data,DATA_SIZE); -<BR> ACE_OS::printf("<< %s\n",data); - -<P> <FONT COLOR="#FF0000">// keep yourself registered with the reactor</FONT> -<BR> return 0; -<BR> } - -<P><FONT COLOR="#FF0000">// new method which returns the handle to the -reactor when it asks for it.</FONT> -<BR>ACE_HANDLE -<BR>get_handle(void) const{ -<BR> return this->peer_.get_handle(); -<BR> } - -<P><FONT COLOR="#FF0000">//new method which returns a reference to the -peer stream</FONT> -<BR>ACE_SOCK_Stream & -<BR>peer(void) const{ -<BR> return (ACE_SOCK_Stream &) this->peer_; -<BR> } -<BR>}; - -<P>int main(int argc, char* argv[]){ -<BR> ACE_INET_Addr addr(PORT_NUM); -<BR> <FONT COLOR="#FF0000">//create the acceptor</FONT> -<BR> MyAcceptor acceptor(addr,<FONT COLOR="#FF0000"> //address to -accept on</FONT> -<BR> ACE_Reactor::instance()); <FONT COLOR="#FF0000">//the reactor -to use</FONT> -<BR>while(1)<FONT COLOR="#FF0000"> // Start the reactors event loop</FONT> -<BR> ACE_Reactor::instance()->handle_events(); -<BR>} -<BR> -<BR> <A HREF="../Chap_7/ex01.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_7/Chap_7.zip b/docs/tutorials/Chap_7/Chap_7.zip Binary files differdeleted file mode 100644 index 0073e63d504..00000000000 --- a/docs/tutorials/Chap_7/Chap_7.zip +++ /dev/null diff --git a/docs/tutorials/Chap_7/ex01.html b/docs/tutorials/Chap_7/ex01.html deleted file mode 100644 index 59c8a3745d0..00000000000 --- a/docs/tutorials/Chap_7/ex01.html +++ /dev/null @@ -1,90 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 1</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Message Queue"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 1</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Message_Queue.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> <FONT COLOR="#006600">"ace/Get_Opt.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">SIZE_BLOCK -1</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">NO_MSGS -10</FONT> - -<P>class QTest{ -<BR>public: -<BR>QTest():no_msgs_(NO_MSGS){ -<BR> <FONT COLOR="#FF0000">//First create a message queue of default -size.</FONT> -<BR> if(!(this->mq_=new ACE_Message_Queue<ACE_NULL_SYNCH> ())) -<BR> ACE_DEBUG((LM_ERROR,"Error in message queue initialization \n")); -<BR> } -<BR> -<BR>int start_test(){ -<BR> for(int i=0; i<no_msgs_;i++){ -<BR> <FONT COLOR="#FF0000">//create a new message block of size 1</FONT> -<BR> ACE_Message_Block *mb= new ACE_Message_Block(SIZE_BLOCK);<FONT COLOR="#FF0000"></FONT> - -<P><FONT COLOR="#FF0000"> //Insert data into the message block using -the rd_ptr</FONT> -<BR> *mb->wr_ptr()=i; - -<P><FONT COLOR="#FF0000"> //Be careful to advance the wr_ptr</FONT> -<BR> mb->wr_ptr(1); - -<P> <FONT COLOR="#FF0000">//Enqueue the message block onto the message -queue</FONT> -<BR> if(this->mq_->enqueue_prio(mb)==-1){ -<BR> ACE_DEBUG((LM_ERROR,"\nCould not enqueue on to mq!!\n")); -<BR> return -1; -<BR> } -<BR> -<BR> ACE_DEBUG((LM_INFO,"EQd data: %d\n",*mb->rd_ptr())); -<BR> } <FONT COLOR="#FF0000">//end for</FONT> - -<P><FONT COLOR="#FF0000">//Now dequeue all the messages</FONT> -<BR>this->dequeue_all(); -<BR>return 0; -<BR> } - -<P>void dequeue_all(){ -<BR> ACE_DEBUG((LM_INFO,"\n\nBeginning DQ \n")); -<BR> ACE_DEBUG((LM_INFO,"No. of Messages on Q:%d Bytes on Q:%d \n",mq_->message_count(), -mq_->message_bytes())); -<BR> ACE_Message_Block *mb; - -<P> <FONT COLOR="#FF0000">//dequeue the head of the message queue -until no more messages are left</FONT> -<BR> for(int i=0;i<no_msgs_;i++){ -<BR> mq_->dequeue_head(mb); -<BR> ACE_DEBUG((LM_INFO,"DQd data %d\n",*mb->rd_ptr())); -<BR> } -<BR> } -<BR>private: -<BR> ACE_Message_Queue<ACE_NULL_SYNCH> *mq_; -<BR> int no_msgs_; -<BR>}; -<BR> - -<P>int main(int argc, char* argv[]){ -<BR> QTest test; -<BR> if(test.start_test()<0) -<BR> ACE_DEBUG((LM_ERROR,"Program failure \n")); -<BR>} - -<P> <A HREF="ex02.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_7/ex02.html b/docs/tutorials/Chap_7/ex02.html deleted file mode 100644 index 3062e546994..00000000000 --- a/docs/tutorials/Chap_7/ex02.html +++ /dev/null @@ -1,165 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 2</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Message Queue"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 2</FONT><FONT COLOR="#000099"></FONT> - -<P><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Message_Queue.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT><FONT COLOR="#006600"> "ace/Get_Opt.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Malloc_T.h"</FONT> -<BR><FONT COLOR="#000099">#define</FONT> <FONT COLOR="#663366">SIZE_BLOCK -1</FONT> - -<P>class Args{ -<BR>public: -<BR>Args(int argc, char*argv[],int& no_msgs, ACE_Message_Queue<ACE_NULL_SYNCH>* -&mq){ -<BR> ACE_Get_Opt get_opts(argc,argv,"h:l:t:n:xsd"); -<BR> while((opt=get_opts())!=-1) -<BR> switch(opt){ -<BR> case 'n': -<BR> <FONT COLOR="#FF0000"> //set the number of messages we -wish to enqueue and dequeue</FONT> -<BR> no_msgs=ACE_OS::atoi(get_opts.optarg); -<BR> ACE_DEBUG((LM_INFO,"Number of Messages %d \n",no_msgs)); -<BR> break; - -<P> case 'h': -<BR> <FONT COLOR="#FF0000">//set the high water mark</FONT> -<BR> hwm=ACE_OS::atoi(get_opts.optarg); -<BR> mq->high_water_mark(hwm); -<BR> ACE_DEBUG((LM_INFO,"High Water Mark %d msgs \n",hwm)); -<BR> break; -<BR> case 'l': -<BR> <FONT COLOR="#FF0000"> //set the low water mark</FONT> -<BR> lwm=ACE_OS::atoi(get_opts.optarg); -<BR> mq->low_water_mark(lwm); -<BR> ACE_DEBUG((LM_INFO,"Low Water Mark %d msgs \n",lwm)); -<BR> break; -<BR> default: -<BR> ACE_DEBUG((LM_ERROR, "Usage -n<no. messages> -h<hwm> --l<lwm>\n")); -<BR> break; -<BR> } -<BR> } - -<P>private: -<BR> int opt; -<BR> int hwm; -<BR> int lwm; -<BR>}; -<BR> -<BR> - -<P>class QTest{ -<BR>public: -<BR>QTest(int argc, char*argv[]){ -<BR><FONT COLOR="#FF0000"> //First create a message queue of default -size.</FONT> -<BR> if(!(this->mq_=new ACE_Message_Queue<ACE_NULL_SYNCH> ())) -<BR> ACE_DEBUG((LM_ERROR,"Error in message queue initialization \n")); -<BR> -<BR> <FONT COLOR="#FF0000">//Use the arguments to set the water marks -and the no of messages</FONT> -<BR> args_ = new Args(argc,argv,no_msgs_,mq_); -<BR> } -<BR>int start_test(){ -<BR> for(int i=0; i<no_msgs_;i++){ -<BR> <FONT COLOR="#FF0000">//Create a new message block of data buffer -size 1</FONT> -<BR> ACE_Message_Block * mb= new ACE_Message_Block(SIZE_BLOCK); -<BR> -<BR><FONT COLOR="#FF0000"> //Insert data into the message block using -the rd_ptr</FONT> -<BR> *mb->wr_ptr()=i; -<BR> -<BR> <FONT COLOR="#FF0000">//Be careful to advance the wr_ptr</FONT> -<BR> mb->wr_ptr(1); - -<P><FONT COLOR="#FF0000"> //Enqueue the message block onto the message -queue</FONT> -<BR> if(this->mq_->enqueue_prio(mb)==-1){ -<BR> ACE_DEBUG((LM_ERROR,"\nCould not enqueue on to mq!!\n")); -<BR> return -1; -<BR> } -<BR> -<BR> ACE_DEBUG((LM_INFO,"EQd data: %d\n",*mb->rd_ptr())); -<BR> } -<BR> <FONT COLOR="#FF0000">//Use the iterators to read</FONT> -<BR> this->read_all(); - -<P> <FONT COLOR="#FF0000">//Dequeue all the messages</FONT> -<BR> this->dequeue_all(); -<BR> return 0; -<BR> } - -<P>void read_all(){ -<BR> ACE_DEBUG((LM_INFO,"No. of Messages on Q:%d Bytes on Q:%d \n", -mq_->message_count(),mq_->message_bytes())); -<BR> ACE_Message_Block *mb; - -<P> <FONT COLOR="#FF0000">//Use the forward iterator</FONT> -<BR> ACE_DEBUG((LM_INFO,"\n\nBeginning Forward Read \n")); -<BR> ACE_Message_Queue_Iterator<ACE_NULL_SYNCH> mq_iter_(*mq_); -<BR> while(mq_iter_.next(mb)){ -<BR> mq_iter_.advance(); -<BR> ACE_DEBUG((LM_INFO,"Read data %d\n",*mb->rd_ptr())); -<BR> } -<BR> -<BR> <FONT COLOR="#FF0000">//Use the reverse iterator</FONT> -<BR> ACE_DEBUG((LM_INFO,"\n\nBeginning Reverse Read \n")); -<BR> ACE_Message_Queue_Reverse_Iterator<ACE_NULL_SYNCH> -<BR> mq_rev_iter_(*mq_); -<BR> while(mq_rev_iter_.next(mb)){ -<BR> mq_rev_iter_.advance(); -<BR> ACE_DEBUG((LM_INFO,"Read data %d\n",*mb->rd_ptr())); -<BR> } -<BR> -<BR> } - -<P>void dequeue_all(){ -<BR> ACE_DEBUG((LM_INFO,"\n\nBeginning DQ \n")); -<BR> ACE_DEBUG((LM_INFO,"No. of Messages on Q:%d Bytes on Q:%d \n", -mq_->message_count(),mq_->message_bytes())); -<BR> ACE_Message_Block *mb; - -<P><FONT COLOR="#FF0000"> //dequeue the head of the message queue -until no more messages are left</FONT> -<BR> for(int i=0;i<no_msgs_;i++){ -<BR> mq_->dequeue_head(mb); -<BR> ACE_DEBUG((LM_INFO,"DQd data %d\n",*mb->rd_ptr())); -<BR> } -<BR> } - -<P>private: -<BR> Args *args_; -<BR> ACE_Message_Queue<ACE_NULL_SYNCH> *mq_; -<BR> int no_msgs_; -<BR>}; -<BR> -<BR> - -<P>int main(int argc, char* argv[]){ -<BR> QTest test(argc,argv); -<BR> if(test.start_test()<0) -<BR> ACE_DEBUG((LM_ERROR,"Program failure \n")); -<BR> -<BR>} - -<P> <A HREF="ex03.html">Next Example</A> -</BODY> -</HTML> diff --git a/docs/tutorials/Chap_7/ex03.html b/docs/tutorials/Chap_7/ex03.html deleted file mode 100644 index 03b6dda63d6..00000000000 --- a/docs/tutorials/Chap_7/ex03.html +++ /dev/null @@ -1,158 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Ambreen Ilyas"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> - <TITLE>Example 3</TITLE> -</HEAD> -<BODY> -<FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> -<BR><FONT COLOR="#CC0000">//// This example is from the ACE Programmers -Guide.</FONT> -<BR><FONT COLOR="#CC0000">//// Chapter: "The Message Queue"</FONT> -<BR><FONT COLOR="#CC0000">//// For details please see the guide at</FONT> -<BR><FONT COLOR="#CC0000">//// http://www.cs.wustl.edu/~schmidt/ACE.html</FONT> -<BR><FONT COLOR="#CC0000">//// AUTHOR: Umar Syyid (usyyid@hns.com)</FONT> -<BR><FONT COLOR="#CC0000">//// and Ambreen Ilyas (ambreen@bitsmart.com)</FONT> -<BR><FONT COLOR="#CC0000">/////////////////////////////////////////////////////////////////////////////////////////////////////////////</FONT> - -<P><FONT COLOR="#CC0000">//Example 3</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Message_Queue.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/Get_Opt.h"</FONT> -<BR><FONT COLOR="#000099">#include</FONT> "<FONT COLOR="#006600">ace/OS.h"</FONT> - -<P>class Args{ -<BR>public: -<BR>Args(int argc, char*argv[],int& no_msgs, int& time,ACE_Message_Queue<ACE_NULL_SYNCH>* -&mq){ -<BR> ACE_Get_Opt get_opts(argc,argv,"h:l:t:n:xsd"); -<BR> while((opt=get_opts())!=-1) -<BR> switch(opt){ -<BR> case 't': -<BR> time=ACE_OS::atoi(get_opts.optarg); -<BR> ACE_DEBUG((LM_INFO,"Time: %d \n",time)); -<BR> break; -<BR> case 'n': -<BR> no_msgs=ACE_OS::atoi(get_opts.optarg); -<BR> ACE_DEBUG((LM_INFO,"Number of Messages %d \n",no_msgs)); -<BR> break; -<BR> case 'x': -<BR> mq=ACE_Message_Queue_Factory<ACE_NULL_SYNCH>:: create_laxity_message_queue(); -<BR> ACE_DEBUG((LM_DEBUG,"Creating laxity q\n")); -<BR> break; -<BR> case 'd': -<BR> mq=ACE_Message_Queue_Factory<ACE_NULL_SYNCH>:: create_deadline_message_queue(); -<BR> ACE_DEBUG((LM_DEBUG,"Creating deadline q\n")); -<BR> break; -<BR> case 's': -<BR> mq=ACE_Message_Queue_Factory<ACE_NULL_SYNCH>:: create_static_message_queue(); -<BR> ACE_DEBUG((LM_DEBUG,"Creating static q\n")); -<BR> break; -<BR> case 'h': -<BR> hwm=ACE_OS::atoi(get_opts.optarg); -<BR> mq->high_water_mark(hwm); -<BR> ACE_DEBUG((LM_INFO,"High Water Mark %d msgs \n",hwm)); -<BR> break; -<BR> case 'l': -<BR> lwm=ACE_OS::atoi(get_opts.optarg); -<BR> mq->low_water_mark(lwm); -<BR> ACE_DEBUG((LM_INFO,"Low Water Mark %d msgs \n",lwm)); -<BR> break; -<BR> default: -<BR> ACE_DEBUG((LM_ERROR,"Usage specify queue type\n")); -<BR> break; -<BR> } -<BR> } - -<P>private: -<BR> int opt; -<BR> int hwm; -<BR> int lwm; -<BR>}; -<BR> -<BR> - -<P>class QTest{ -<BR>public: -<BR>QTest(int argc, char*argv[]){ -<BR> args_ = new Args(argc,argv,no_msgs_,time_,mq_); -<BR> array_ =new ACE_Message_Block*[no_msgs_]; -<BR> } - -<P>int start_test(){ -<BR> for(int i=0; i<no_msgs_;i++){ -<BR> ACE_NEW_RETURN (array_[i], ACE_Message_Block (1), -1); -<BR> set_deadline(i); -<BR> set_execution_time(i); -<BR> enqueue(i); -<BR> } - -<P> this->dequeue_all(); -<BR> return 0; -<BR> } - -<P><FONT COLOR="#FF0000">//Call the underlying ACE_Message_Block method -msg_deadline_time() to set the deadline of the message.</FONT> -<BR>void set_deadline(int msg_no){ -<BR> float temp=(float) time_/(msg_no+1); -<BR> ACE_Time_Value tv; -<BR> tv.set(temp); -<BR> ACE_Time_Value deadline(ACE_OS::gettimeofday()+tv); -<BR> array_[msg_no]->msg_deadline_time(deadline); -<BR> ACE_DEBUG((LM_INFO,"EQd with DLine %d:%d\n", deadline.sec(),deadline.usec())); -<BR> } - -<P><FONT COLOR="#FF0000">//Call the underlying ACE_Message_Block method -to set the execution time</FONT> -<BR>void set_execution_time(int msg_no){ -<BR> float temp=(float) time_/10*msg_no; -<BR> ACE_Time_Value tv; -<BR> tv.set(temp); -<BR> ACE_Time_Value xtime(ACE_OS::gettimeofday()+tv); -<BR> array_[msg_no]->msg_execution_time (xtime); -<BR> ACE_DEBUG((LM_INFO,"Xtime %d:%d\n",xtime.sec(),xtime.usec())); -<BR> } - -<P>void enqueue(int msg_no){ -<BR><FONT COLOR="#FF0000"> //Set the value of data at the read position</FONT> -<BR> *array_[msg_no]->rd_ptr()=msg_no; -<BR><FONT COLOR="#FF0000"> //Advance write pointer</FONT> -<BR> array_[msg_no]->wr_ptr(1); -<BR><FONT COLOR="#FF0000"> //Enqueue on the message queue</FONT> -<BR> if(mq_->enqueue_prio(array_[msg_no])==-1){ -<BR> ACE_DEBUG((LM_ERROR,"\nCould not enqueue on to mq!!\n")); -<BR> return; -<BR> } -<BR> ACE_DEBUG((LM_INFO,"Data %d\n",*array_[msg_no]->rd_ptr())); -<BR> } - -<P>void dequeue_all(){ -<BR> ACE_DEBUG((LM_INFO,"Beginning DQ \n")); -<BR> ACE_DEBUG((LM_INFO,"No. of Messages on Q:%d Bytes on Q:%d \n", -mq_->message_count(),mq_->message_bytes())); -<BR> for(int i=0;i<no_msgs_ ;i++){ -<BR> ACE_Message_Block *mb; -<BR> if(mq_->dequeue_head(mb)==-1){ -<BR> ACE_DEBUG((LM_ERROR,'\nCould not dequeue from mq!!\n")); -<BR> return; -<BR> } -<BR> ACE_DEBUG((LM_INFO,"DQd data %d\n",*mb->rd_ptr())); -<BR> } -<BR> } -<BR>private: -<BR> Args *args_; -<BR> ACE_Message_Block **array_; -<BR> ACE_Message_Queue<ACE_NULL_SYNCH> *mq_; -<BR> int no_msgs_; -<BR> int time_; -<BR>}; - -<P>int main(int argc, char* argv[]){ -<BR> QTest test(argc,argv); -<BR> if(test.start_test()<0) -<BR> ACE_DEBUG((LM_ERROR,"Program failure \n")); -<BR> -<BR>} -<BR> -</BODY> -</HTML> diff --git a/docs/tutorials/Makefile b/docs/tutorials/Makefile deleted file mode 100644 index 25c5aa17f17..00000000000 --- a/docs/tutorials/Makefile +++ /dev/null @@ -1,9 +0,0 @@ - -# $Id$ - -all clean realclean : # - for i in * ; do \ - [ -f $$i/Makefile ] || continue ; \ - ( cd $$i ; $(MAKE) $@ ) ; \ - done -include .depend diff --git a/docs/tutorials/colorize b/docs/tutorials/colorize deleted file mode 100755 index 5b324eac473..00000000000 --- a/docs/tutorials/colorize +++ /dev/null @@ -1,18 +0,0 @@ -eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -while( <STDIN> ) -{ - s/</\</g; - s,\#(e?l?if !?defined|pragma|ifn?def|define)(\W*)([\w\.]+),<font color=blue>\#$1</font>$2<font color=purple>$3</font>,; - s,\#(include|endif),<font color=blue>$&</font>,; - s,"([^"]+)","<font color=green>$1</font>",g; - s,//.*$,<font color=red>$&</font>,; - s,/\*,<font color=red>$&,; - s,\*/,$&</font>,; - s,\w+::\~?\w+,<font color=\#008888>$&</font>,; - print STDOUT $_; -} - -0; diff --git a/docs/tutorials/combine b/docs/tutorials/combine deleted file mode 100755 index 7d29dab60d4..00000000000 --- a/docs/tutorials/combine +++ /dev/null @@ -1,157 +0,0 @@ -eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -# -# This perl script will combine a set of files into one or more HTML pages. -# -# The file fooNN.html will be created by combining the files: -# fooNN.hdr -# fooNN.pre -# fooNN.bdy -# fooNN.pst -# -# Where NN is a 2-digit number. If fooNN.hdr does not exist, the file 'hdr' -# will be used. If any of the other file-parts don't exist, they will be -# ignored. -# -# Usage: -# combine *.html -# combine *.pre -# -# Input files: -# -# -# hdr -# If no *.hdr exists for the current page, this is used. You will typically -# use this to add <TITLE> and such to each page created. -# -# *.hdr -# You can override the generic hdr you create by creating one for -# a specific page. -# -# *.pre -# Prefix files. Their content is included after the hdr. -# -# *.bdy -# Body files follow prefix. You generally use the links file to create -# links between source-code and a bdy filename. The bdy files are -# examined and "fontified" (think emacs). -# -# bodies -# The list of files to use for the body of the HTML pages generated -# -# *.pst -# Post files. This content follows the bdy content. -# -# *.html -# These are the output. If they exist before you run combine, they -# will be overwritten. -# -use File::Copy; - -%format = (); - -$PAGE=0; - -open(LINKS,"<bodies") || die("No 'bodies' file found!"); -while( ($file = <LINKS>) ) { - - chomp($file); - - next if( $file =~ /^#/ || $file eq '' ); - - if( $file =~ /^.*=/ ) { - ($var,$value) = split(/=/,$file); - if( $var =~ /PAGE/ ) { - $PAGE = $value + 0; - } - next; - } - - $body{$PAGE++} = "$file"; -} -close(LINKS); - -foreach $file (@ARGV) { - ($base = $file) =~ s/.html$//; - $base =~ s/.pre$//; - - open(FILE,">$base.html") || die; - select(FILE); - $| = 1; - - # .hdr has the HTML header, title, etc... - if( -f "$base.hdr" ) { - copy("$base.hdr",\*FILE); - } - elsif( -f "hdr" ) { - copy("hdr",\*FILE); - } - # .pre has the discussion of what you'll see on this page - if( -f "$base.pre" ) { - copy("$base.pre",\*FILE); - } - # .bdy is the body of the page - if( -f "$base.bdy" ) { - &addFile("$base.bdy"); - } - - ($num = $base) =~ s/[A-z]//g; - $num += 0; - - if( -f "$body{$num}" || "$body{$num}" =~ /\s/ ) { - &addFile("$body{$num}"); - } - # .pst summarizes what was seen - if( -f "$base.pst" ) { - copy("$base.pst",\*FILE); - } - # .ftr follows the footer to show "continue to next page" stuff - if( -f "$base.ftr" ) { - copy("$base.ftr",\*FILE); - } - else { - ++$num; - $base =~ s/[0-9]//g; - $next = sprintf("$base%02.2d",$num); - print FILE "<P><HR WIDTH=\"100%\">\n"; - print FILE "<CENTER>[<A HREF=\"../online-tutorials.html\">Tutorial Index</A>] "; - if( $file ne $ARGV[$#ARGV] ) { - print FILE "[<A HREF=\"$next.html\">Continue This Tutorial</A>]"; - } - print FILE "</CENTER>\n"; - } - close(FILE); -} - -sub addFile { - local($file) = @_; - - local(@file) = split(/\s+/,$file); - - foreach $file (@file) - { - if( $#file > 0 ) - { - print FILE "<HR width=50%><P><center>$file</center><HR width=50%>\n"; - } - print FILE "<PRE>\n" ; - open(INPUT,"<$file") || die "Cannot open $file for read\n"; - # Do some substitutes on each line to try and get the output to - # look like it does in fontified emacs. - while( <INPUT> ) - { - s/</\</g; - s,\#(e?l?if !?defined|pragma|ifn?def|define)(\W*)([\w\.]+),<font color=blue>\#$1</font>$2<font color=purple>$3</font>,; - s,\#(include|endif),<font color=blue>$&</font>,; - s,"([^"]+)","<font color=green>$1</font>",g; - s,//.*$,<font color=red>$&</font>,; - s,/\*,<font color=red>$&,; - s,\*/,$&</font>,; - s,\w+::\~?\w+,<font color=\#008888>$&</font>,; - print FILE $_; - } - print FILE "</PRE>\n"; - } -} diff --git a/docs/tutorials/fix.Makefile b/docs/tutorials/fix.Makefile deleted file mode 100755 index 8e3d2ac9187..00000000000 --- a/docs/tutorials/fix.Makefile +++ /dev/null @@ -1,68 +0,0 @@ -eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -require "getopts.pl"; -&Getopts("f:o:"); - -$opt_f = "Makefile" if( ! $opt_f ); -$opt_o = ".depend" if( ! $opt_o ); - - # Open the Makefile that has been mangled by 'make depend' - # and suck it into a perl array. -open(IF,"<$opt_f") || die; -@makefile = <IF>; -close(IF); - - # Now open our .depend file and a temporary Makefile. - # We'll split the original Makefile between these two. -open(DF,">$opt_o") || die; -open(MF,">$opt_f.tmp") || die; - - # For each line we read out of the original file... -foreach (@makefile) { - - # If we're into the dependency section, write the line - # into the .depend file. - # - if( $depend ) { - print DF $_; - } - else { - # If we haven't gotten to the dependency section yet - # then see if the current line is the separator that - # "make depend" causes to be inserted. - # - if( m/^\Q# DO NOT DELETE THIS LINE -- g++dep uses it.\E/ ) { - - # If so, change our "mode" and skip this line. - ++$depend; - next; - } - - # Also skip the "include .depend" that we insert. If we - # don't do this, it is possible to have a bunch of these - # inserted into the output when we read an unmangled Makefile - next if( m/^include $opt_o/ ); - - # Print the non-dependency info to the temporary Makefile - print MF $_; - } -} - -# Tell our new Makefile to include the dependency file -print MF "include $opt_o\n"; - -# Close the two output files... -close(DF); -close(MF); - -# Unlink (remove) the original Makefile and rename our -# temporary file. There's obviously room for error checking -# here but we've got the Makefile checked into some revision -# control system anyway. Don't we? - -unlink("$opt_f"); -rename("$opt_f.tmp","$opt_f"); - -exit(0); diff --git a/docs/tutorials/guide-tutorials.html b/docs/tutorials/guide-tutorials.html deleted file mode 100644 index fdb3083cb66..00000000000 --- a/docs/tutorials/guide-tutorials.html +++ /dev/null @@ -1,46 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; SunOS 5.5.1 sun4u) [Netscape]"> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#333333" ALINK="#FE0000"> - -<HR WIDTH="100%"><P> -<H3>Online Examples from the ACE Programmers Guide</H3> - -The following page has links to the example code that is presented in -the <A HREF="http://www.cs.wustl.edu/~schmidt/ACE-tutorials.ps.gz">ACE -programmers guide</a>. The guide was created at <A -HREF="http://www.hns.com">Hughes Network Systems</A>. Questions -regarding the guide should be sent to <A -HREF="mailto:usyyid@hns.com">Umar Syyid <usyyid@hns.com></A> - -<P> -<HR WIDTH="100%"> -<H3>Chapter Breakdown</H3> - - -<H4> Chapter 2: <A HREF="Chap_2/ex01.html">IPC _SAP</A></H4> - -<H4> Chapter 3: <A HREF="Chap_3/ex01.html">Memory Management</A></H4> - -<H4> Chapter 4: <A HREF="Chap_4/ex01.html">Thread Management</A></H4> - -<H4> Chapter 5: Tasks and Active Objects</H4> - -<H4> Chapter 6: <A HREF="Chap_5/ex01.html">The Reactor</A></H4> - -<H4> Chapter 7: <A HREF="Chap_6/ex01.html">The Acceptor and Connector</A></H4> - -<H4> Chapter 8: The Service Configurator</H4> - -<H4> Chapter 9: <A HREF="Chap_7/ex01.html">Message Queues</A></H4> - -<P><HR> - -<P>Back to the <A HREF="../ACE-tutorials.html">ACE tutorials</A> page. - -<P> -<!--#include virtual="/~schmidt/cgi-sig.html" --> -</BODY> -</HTML> diff --git a/docs/tutorials/linify b/docs/tutorials/linify deleted file mode 100755 index ad2016905ff..00000000000 --- a/docs/tutorials/linify +++ /dev/null @@ -1,54 +0,0 @@ -eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -while( $#ARGV > -1 ) { - - print "$ARGV[0]\n"; - - $source = "$ARGV[0]"; - - if( $source =~ /~$/ ) { - $dest = "$`"; - } else { - rename("$source","$source"."~") || die "Cannot rename ($source)"; - $dest = "$source"; - $source .= "~"; - } - - open(INPUT,"<$source") || die "Cannot open ($source)"; - open(OUTPUT,">$dest") || die "Cannot open ($dest)"; - - $n = 1; - - $prestrip = 0; - while( <INPUT> ) { - chomp; - - if( ! $prestrip && /^[0-9]+\.\t/ ) { - $prestrip = 1; - $_ = $'; - } elsif( $prestrip ) { - if( /^[0-9]+\.\t/ ) { - $_ = $'; - } else { - s/^\t//; - } - } - - if( /^\s*$/ || /^\s*({|})\s*;?\s*$/ || /^\s*\/\// - || /^\s*private\s*:/ || /^\s*protected\s*:/ || /^\s*public\s*:/ - || /^\s*}?\s*else\s*{?\s*:/ - ) { - print OUTPUT "\t$_\n"; - } else { - print OUTPUT "$n.\t$_\n"; - ++$n; - } - } - - close(INPUT); - close(OUTPUT); - - shift(@ARGV); -} diff --git a/docs/tutorials/new-tutorials.html b/docs/tutorials/new-tutorials.html deleted file mode 100644 index af3846b7af7..00000000000 --- a/docs/tutorials/new-tutorials.html +++ /dev/null @@ -1,80 +0,0 @@ -<TITLE>ACE Beginners' Guide</TITLE> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - -<HR><P> -<H3>Developing New Tutorials</H3> - -Here are some general guidelines for creating new ACE tutorials: <P> - -<hr width=50% align=left> -<H4>Choose a Topic You Know Very Well (or are just learning)</h4> - - This isn't really a conflict... -<P> - If you know a topic very well, you're likely to know what is most - important to the novice and what can be left until later. If you're - just learning a topic, then you know what questions you have that - must be answered before you can continue. -<P> -<hr width=50% align=left> -<H4> Keep It Simple</H4> -<P> - Don't try to use a lot of really cool ACE features along the way. Stick - to the basic stuff and show that. Try to use a minimum of ACE objects - that are not the direct target of the tutorial. -<P> - (For instance, don't get all caught up in ACE_Singleton<> if you're - trying to show how to use an ACE_Reactor.) -<P> - If you want to show something really cool that happens to depend on - another ACE feature, do a tutorial on that other feature first! I've - found that folks will tend to get stuck on *anything* they don't - understand even if it isn't directly relevant to what you're trying - to teach. -<P> -<hr width=50% align=left> -<h4>Document the Heck Out of It!</H4> -<P> - There's no such thing as too much documentation. Don't worry about - repeating yourself along the way. Assume that the reader knows nothing - at all about the topic at hand and explain even the parts that you feel - are painfully obvious. -<P> - If you feel that sticking a bunch of comments in the code makes it harder - to read then stick in a label and document at the end of the file or - something. Alternately, create both a well-documented version and a - sparsely-documented version. Then folks can choose between 'em. -<P> -<hr width=50% align=left> -<h4>Over-teach It</H4> -<P> - If there's a tutorial created for a topic that you feel strong in, - create another one anyway. Everybody tends to code a little differently. - Perhaps your tutorial style will "feel" better to some newcomers - than an existing tutorial. You won't hurt anybody's feelings if - you present the same material in a different way. -<P> -<hr width=50% align=left> -<h4>Leverage Existing Code</H4> -<P> - The ultimate form of code reuse :-) Seriously... grab one or more - of the existing ACE tests or examples. Then strip it down to the - bare bones & add heaps of comments. I don't think the software-police - will be coming after anyone for that! - -<P> If this thing takes off, I'll start to organize the tutorials into -groups. For now, lets concentrate on quantity & quality. -Organization can come later... <P> - -<HR><P> <H3> What about TAO?</H3> In the early stages, these tutorials -won't address The ACE ORB (<A -HREF="http://www.cs.wustl.edu/~schmidt">TAO</A>). However, if you -want to request a tutorial on some aspect of TAO or even create one -yourself, I'll be glad to integrate those into these tutorials. It's -rare when folks want to write documentation, so nothing will be -refused!<P> - -<HR><P> -Back to the <A -HREF="../ACE-tutorials.html">ACE -tutorials</A> page. diff --git a/docs/tutorials/online-tutorials.html b/docs/tutorials/online-tutorials.html deleted file mode 100644 index 7aa97414562..00000000000 --- a/docs/tutorials/online-tutorials.html +++ /dev/null @@ -1,143 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>Online ACE Tutorials</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<HR> -<H3> -Online ACE Tutorials</H3> - -The following online tutorials are designed to help get you started -with ACE. The original audience for these tutorials was the <A -HREF="http://www.lads.com">Automated Design Systems</A> (ADS) IPC -team, lead by <A HREF="mailto:jcej@lads.com">James Johnson</A>. Since -then, the scope has been changed to include anyone who wants to learn -about the ACE framework. Hopefully, even experienced ACE programmers -will find something new here. With a framework as encompassing as ACE, -it is easy to become an expert in one area and know little or nothing -about others. <P> - -<FONT size=-1>Before you try compiling Tutorial 2 (and beyond) you -might want to read these comments about <A HREF="templates.html">C++ -templates</A></font> <P> - -<P><HR WIDTH="50%" align=left><P> -<H4> -Your basic Client/Server hookup</H4> - -<OL> -<LI> -<A HREF="001/page01.html">A -Simple Server</A></LI> - -<LI> -<A HREF="002/page01.html">A -Simpler Server</A></LI> - -<LI> -<A HREF="003/page01.html">Finally, -a Client</A></LI> - -<LI> -<A HREF="004/page01.html">A -much <I>cooler</I> client</A></LI> -</OL> - -<P><HR WIDTH="50%" align=left><P> -<H4> -A word about concurrency</H4> - -<OL> -<LI> -<A HREF="005/page01.html">No -threads, nothing fancy, just do the work!</A></LI> - -<LI> -<A HREF="006/page01.html">I'd -like to dedicate... a thread to each connection.</A></LI> - -<LI> -<A HREF="007/page01.html">Let's -pool our resources: a fixed-size pool of threads.</A></LI> -</OL> - -<P><HR WIDTH="50%" align=left><P> -<H4> -Finding servers on your network</H4> - -<OL> -<LI> -<A HREF="008/page01.html">Calling -all servers!</A></LI> - -<LI> -<A HREF="009/page01.html">Discriminating tastes...</A></LI> -</OL> - -<P><HR WIDTH="50%" align=left><P> - -<H4> -A word about ACE_Message_Queue</H4> - -<OL> -<LI> -<A HREF="010/page01.html">Puttin' data</A></LI> -<LI> -<A HREF="011/page01.html">What about non-trivial data?</A></LI> -<LI> -<A HREF="012/page01.html">Puttin' pointers</A></LI> -<LI> -<A HREF="013/page01.html">Task chains and state machines</A></LI> -</OL> - -<P><HR WIDTH="50%" align=left><P> - -<H4> -Paddling down (and up) the ACE_Stream</H4> - -<OL> -<LI> -<A HREF="014/page01.html">ACE_Stream Tutorial, Of Sorts</A></LI> -<LI> -<A HREF="015/page01.html">A certain amount of Protocol is required!</A></LI> -</OL> - -<P><HR WIDTH="50%" align=left><P> - -<H4> -Keeping yourself in synch</H4> -<OL> -<LI> -<A HREF="016/page01.html">On one condition...</A> -<LI> -<A HREF="017/page01.html">Something about Barriers</A> -<LI> -<A HREF="018/page01.html">Tokens & templates</A> -</OL> - -<P><HR WIDTH="50%" align=left><P> - -<H4> -Do you remember...</H4> -<OL> -<LI> -<A HREF="019/page01.html">Using System V Shared Memory for telepathy</A> -<LI> -<A HREF="020/page01.html">Never forget anything else again!</A> -<LI> -<A HREF="021/page01.html">Pooling your memories via ACE_Malloc</A> -</OL> - -<HR> - -<P>Back to the <A HREF="../ACE-tutorials.html">ACE tutorials</A> page. - -<P> -<!--#include virtual="/~schmidt/cgi-sig.html" --> -</BODY> -</HTML> - diff --git a/docs/tutorials/templates.html b/docs/tutorials/templates.html deleted file mode 100644 index 9fbf452d8dd..00000000000 --- a/docs/tutorials/templates.html +++ /dev/null @@ -1,188 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>About C++ Templates</title> - </head> - - <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -<center> - <h1>About C++ Templates</h1> -</center> - - - <hr> - -When you get to server.cpp in Tutorial 2 you'll see these lines at the bottom: -<P> -<UL> -<PRE> -<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>) -template class ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font> -Thanks to Krishna Padmasola for providing these. -</PRE> -</UL> -<P> -What's that all about? -<P> -Well, if you've been doing ACE for more than about 30 seconds you will -have run into the joys and sorrows of C++ templates. They're really -great things that prevent the need for complex #define'd macros, -ensure type safety and do other really nifty things. One of the -problems, however, is that not all compilers can figure out what -templates you need. -<P> -Take the simple templated class: -<UL> -<PRE> - -template <class DATATYPE> -class MyTemplate -{ -public: - MyTemplate(void) - { - } - - DATATYPE data(void) - { - return data_; - } - - void data( DATATYPE _data ) - { - data_ = _data; - } - -protected: - - DATATYPE data_; -}; -</PRE> -</UL> -<P> -Now suppose you write the following code fragment: -<P> -<UL> -<PRE> -int main(int,char**) -{ - MyTemplate<int> itemp; - MyTemplate<char> ctemp; - - ... -} -</pre> -</ul> -<P> -Some compilers will take care of you and automatically generate the -equivalent classes: -<UL> -<pre> -class MyTemplate -{ -public: - MyTemplate(void) - { - } - - int data(void) - { - return data_; - } - - void data( int _data ) - { - data_ = _data; - } - -protected: - - int data_; -}; - -class MyTemplate -{ -public: - MyTemplate(void) - { - } - - char data(void) - { - return data_; - } - - void data( char _data ) - { - data_ = _data; - } - -protected: - - char data_; -}; -</pre> -</ul> -<P> -On the other hand, some compilers will complain loudly about undefined -symbols and all sorts of other things. When Clinton Carr compiled -server.cpp of Tutorial 2 on his RedHat 5.1 (gcc) system, for instance, -he was rewarded with these lovely errors: -<P> -<UL> -<PRE> -server.cpp:60: undefined reference to `ACE_Acceptor<Client_Handler, ACE_SOCK_Acceptor>::ACE_Acceptor(ACE_Reactor *)' -server.cpp:72: undefined reference to `ACE_Acceptor<Client_Handler, ACE_SOCK_Acceptor>::open(ACE_INET_Addr const &, ACE_Reactor *,int)' -server.cpp:73: undefined reference to `ACE_Acceptor<Client_Handler, ACE_SOCK_Acceptor>::~ACE_Acceptor(void)' -server.cpp:112: undefined reference to `ACE_Acceptor<Client_Handler, ACE_SOCK_Acceptor>::~ACE_Acceptor(void)' - -</PRE> -</UL> -<P> -Figuring out the correct manual instantiations is usually an -interative and tedious process. On Linux, I generally use a version of gcc that -will do automatic instantiaion. "Normal" gcc with the Cygnus repo -patches does that as does egcs. Lately (9/98) I've been using egcs -1.1b with pretty good results. On our Digital Unix 4.0b system the -native compiler (CXX) has switches that will request it to also -automatically instantiate templates as needed. -<P> -The tradeoffs? -<P> -If you choose to do manual instantiation then your code will work just -about anywhere ACE will. For complex applications, it can take a -number of hours to get things right. -<P> -If you choose to let the compiler do instantiations for you then it -will perform the iterative process. That means that every compile -will be longer than without manual instantiations. -<P> -Compromise? -<P> -Yes, you can do that. You can manually instantiate some -templates and let the compiler get the rest. Some compilers will -generate output that you can then use to figure out the correct -templates. Gcc/egcs create .rpo files for each object. These files -contain mangled names that the compiler uses to figure out what to -instantiate. With c++filt and some patience, you can parse that stuff -to figure out what the compiler is instantiating for you. -<P> -My best advice is to get a compiler that will handle the -instantiations for you. When you have some free time on your hands, -take a look at it's intermediate files (if any) and start working on -manual instantiation. -<P> -For some more hints, take a look at <A HREF="../../ACE-INSTALL.html#g++">ACE-INSTALL</A> -<P> - <hr> - -Thanks to Amos Shapira for catching a number of errors here. - - </body> -</html> -
\ No newline at end of file diff --git a/docs/tutorials/tutorials.dsw b/docs/tutorials/tutorials.dsw deleted file mode 100644 index 283bc05eb44..00000000000 --- a/docs/tutorials/tutorials.dsw +++ /dev/null @@ -1,413 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "001"=.\001\001.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "002"=.\002\002.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "003"=.\003\003.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "004"=.\004\004.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "005"=.\005\005.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "006"=.\006\006.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "007"=.\007\007.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "008 broadcast"=".\008\008-broadcast.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "008 direct"=".\008\008-direct.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "008 server"=".\008\008-server.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "009 broadcast"=".\009\009-broadcast.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "009 directed"=".\009\009-directed.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "009 server"=".\009\009-server.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "010"=.\010\010.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "011"=.\011\011.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "012"=.\012\012.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "013"=.\013\013.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "014"=.\014\014.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "015 client"=".\015\015-client.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "015 server"=".\015\015-server.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "016"=.\016\016.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "017"=.\017\017.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "018"=.\018\018.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "019 client"=".\019\019 client.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "019 client2"=".\019\019 client2.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "019 server"=".\019\019 server.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "019 server2"=".\019\019 server2.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "020 client"=".\020\020 client.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "020 client2"=".\020\020 client2.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "020 server"=".\020\020 server.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "020 server2"=".\020\020 server2.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "021 client"=".\021\021 client.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Project: "021 server"=".\021\021 server.dsp" - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
|