diff options
Diffstat (limited to 'docs/tutorials/001')
-rw-r--r-- | docs/tutorials/001/001.dsp | 108 | ||||
-rw-r--r-- | docs/tutorials/001/00SetEnv | 2 | ||||
-rw-r--r-- | docs/tutorials/001/Makefile | 56 | ||||
-rw-r--r-- | docs/tutorials/001/acceptor.h | 148 | ||||
-rw-r--r-- | docs/tutorials/001/combine.shar | 574 | ||||
-rw-r--r-- | docs/tutorials/001/logger.h | 177 | ||||
-rw-r--r-- | docs/tutorials/001/page01.html | 102 | ||||
-rw-r--r-- | docs/tutorials/001/page02.html | 178 | ||||
-rw-r--r-- | docs/tutorials/001/page03.html | 215 | ||||
-rw-r--r-- | docs/tutorials/001/page04.html | 210 | ||||
-rw-r--r-- | docs/tutorials/001/page05.html | 54 | ||||
-rw-r--r-- | docs/tutorials/001/server.cpp | 85 | ||||
-rw-r--r-- | docs/tutorials/001/simple.fig | 57 | ||||
-rw-r--r-- | docs/tutorials/001/simple.gif | bin | 6040 -> 0 bytes |
14 files changed, 0 insertions, 1966 deletions
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 cf0d529e3ea..00000000000 --- a/docs/tutorials/001/Makefile +++ /dev/null @@ -1,56 +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 -#---------------------------------------------------------------------------- - -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 - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -.obj/server.o .shobj/server.so: server.cpp acceptor.h logger.h - 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/combine.shar b/docs/tutorials/001/combine.shar deleted file mode 100644 index 8dcf0ab3f72..00000000000 --- a/docs/tutorials/001/combine.shar +++ /dev/null @@ -1,574 +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-17 14:14 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/001'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 524 -rw-rw-r-- hdr -# 38 -rw-rw-r-- bodies -# 4034 -rw-rw-r-- page01.pre -# 2188 -rw-rw-r-- page02.pre -# 553 -rw-rw-r-- page03.pre -# 79 -rw-rw-r-- page04.pre -# 1149 -rw-rw-r-- page05.pre -# 478 -rw-rw-r-- page02.pst -# 1434 -rw-rw-r-- page03.pst -# 279 -rw-rw-r-- page04.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 _sh00080; 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' && -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> -X <TITLE>ACE Tutorial 001</TITLE> -X <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> -X -X -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> -X -<hr> -SHAR_EOF - $shar_touch -am 0117141099 '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' -1d643c1c0995e071a0a9e3662d7a440b hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 524 -eq "$shar_count" || - $echo 'hdr:' 'original size' '524,' '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 -acceptor.h -logger.h -SHAR_EOF - $shar_touch -am 0117140699 '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' -20ddb6c1ff71a6481ce0956f1a70a612 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 38 -eq "$shar_count" || - $echo 'bodies:' 'original size' '38,' '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' && -<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 tutorials.</P> -X -<P> -<HR WIDTH="100%"></P> -X -<P>What do you need to create a server?</P> -X -<OL> -<LI>Something which accepts connections from clients</LI> -X -<LI>Something which handles established connections</LI> -X -<LI>A main program loop that handles it all</LI> -</OL> -X -<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> -X -<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> -X -<P>Finally, a simple <I>main()</I> function will provide our program loop. -After any program initialization, it will enter an infinite loop which -waits for connection attempts to the Acceptor or data "events" -on the EventHandler.</P> -X -<P> -<HR WIDTH="100%"></P> -X -<P>Before we continue, I need to introduce one more ACE concept: the Reactor. -</P> -X -<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> -X -<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> -X -<P>Why use the reactor?</P> -X -<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> -X -<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> -X -<P>This is where the reactor's power and flexibility come into play. The -developer can create 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 and makes you think that ACE is way to hard to -learn, don't worry. We'll go into all the details and 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> -SHAR_EOF - $shar_touch -am 0117140899 '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' -58b12a93efda94c99be5d0b38c3096a5 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 4034 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '4034,' '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>From here, we 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. -X -<P>The <A HREF="server.cpp">main</A> -program is really quite simple. The real work is done in the ACE derived -classes. -X -<P> -Kirthika Parameswaran offers this abstract of Tutorial 1: -<UL> -<P> -This is a 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_Handler for the Reactor and hence no special processing is needed -for it. -<P> -Once a connection request occurs, the Acceptor accepts it and -a 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> -FYI (from Doug): -<UL> -The ACCEPT_MASK is defined in the ACE_Event_Handler class. It's used -to inform the Reactor that you want to register an event handler to -"accept" a connection passively. Not surprisingly, the ACE_Acceptor -component uses this. -<P> -The READ_MASK is also defined in the ACE_Event_Handler class. It's -used to inform the Reactor that you want to register an event handler -to "read" data from an established connection. -</UL> -<hr> -SHAR_EOF - $shar_touch -am 0117140999 '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' -5e23294cf842366a9ca1b14867856359 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 2188 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '2188,' '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>Now we begin to look at the <A HREF="acceptor.h">acceptor</A> object. -X -<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> -SHAR_EOF - $shar_touch -am 0117140999 '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' -b1eca88136f15c2c1156a2602daaff7e page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 553 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '553,' '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>Now we begin to look at the <A HREF="logger.h">logger</A> -object. -X -<P> -<HR> -SHAR_EOF - $shar_touch -am 0117140999 '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' -ea4861a868e3dce3607602f1ce35b7fa page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 79 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '79,' '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>This concludes the first tutorial on using ACE. We've learned how to -create a simple server without knowing very much about network programming. -X -<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 and I'll integrate it into the tutorial. -X -<UL> -<LI> -<A HREF="00SetEnv">Environment -Settings</A></LI> -X -<LI> -<A HREF="Makefile">Makefile</A></LI> -X -<LI> -<A HREF="server.cpp">main -program</A></LI> -X -<LI> -<A HREF="acceptor.h">acceptor -object</A></LI> -X -<LI> -<A HREF="logger.h">connection -handler</A></LI> -</UL> -X -<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> -SHAR_EOF - $shar_touch -am 0117141399 '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' -7d00b8c59c4f7210634bc5fdb75dfbcc page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 1149 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '1149,' '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%"> -X -<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> -X -<LI> -Create an acceptor which listens on that address</LI> -X -<LI> -Register the acceptor with a reactor to respond to the connection requests</LI> -X -<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. -X -<P> -SHAR_EOF - $shar_touch -am 0117141299 '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' -51b1f08eabda5789182b566fdb7756fe page02.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`" - test 478 -eq "$shar_count" || - $echo 'page02.pst:' 'original size' '478,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pst ============== -if test -f 'page03.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pst' '(file already exists)' -else - $echo 'x -' extracting 'page03.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pst' && -<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. -X -<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. -X -<P> -SHAR_EOF - $shar_touch -am 0117141299 'page03.pst' && - chmod 0664 'page03.pst' || - $echo 'restore of' 'page03.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 'page03.pst:' 'MD5 check failed' -7a18def18c6a83a1015e08f63b5868be page03.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pst'`" - test 1434 -eq "$shar_count" || - $echo 'page03.pst:' 'original size' '1434,' '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%"> -X -<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> -SHAR_EOF - $shar_touch -am 0117141299 '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' -5baa295de79c6c978bae3e496e32854e page04.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`" - test 279 -eq "$shar_count" || - $echo 'page04.pst:' 'original size' '279,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh00080 -exit 0 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 3155a0b9c18..00000000000 --- a/docs/tutorials/001/page01.html +++ /dev/null @@ -1,102 +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> - -<hr> -<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 tutorials.</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 initialization, 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 create 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 and makes you think that ACE is way to hard to -learn, don't worry. We'll go into all the details and 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> -<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/001/page02.html b/docs/tutorials/001/page02.html deleted file mode 100644 index dff82baa375..00000000000 --- a/docs/tutorials/001/page02.html +++ /dev/null @@ -1,178 +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> - -<hr> -<P>From here, we 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 a 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_Handler for the Reactor and hence no special processing is needed -for it. -<P> -Once a connection request occurs, the Acceptor accepts it and -a 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> -FYI (from Doug): -<UL> -The ACCEPT_MASK is defined in the ACE_Event_Handler class. It's used -to inform the Reactor that you want to register an event handler to -"accept" a connection passively. Not surprisingly, the ACE_Acceptor -component uses this. -<P> -The READ_MASK is also defined in the ACE_Event_Handler class. It's -used to inform the Reactor that you want to register an event handler -to "read" data from an established connection. -</UL> -<hr> -<PRE> - -<font color=red>// $Id$</font> - - -<font color=red>/* - Include the header file where our client acceptor is defined. - */</font> -<font color=blue>#include</font> "<font color=green>ace/Reactor.h</font>" - -<font color=red>/* - 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. -*/</font> -ACE_Reactor * g_reactor; - -<font color=red>/* - Include the header where we define our acceptor object. An acceptor is - an abstraction that allows a server to "<font color=green>accept</font>" connections from clients. -*/</font> -<font color=blue>#include</font> "<font color=green>acceptor.h</font>" - -<font color=red>/* - 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. -*/</font> -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int main (int, char *[]) -{ - <font color=red>/* - 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. - */</font> - g_reactor = new ACE_Reactor; - - <font color=red>/* - 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. - */</font> - ACE_INET_Addr addr (PORT); - - <font color=red>/* - We now create an acceptor object. No connections will - yet be established because the object isn't "<font color=green>open for business</font>" - at this time. Which brings us to the next line... - */</font> - Logging_Acceptor * peer_acceptor = new Logging_Acceptor(); - - <font color=red>/* - 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. - */</font> - if (peer_acceptor->open(addr,g_reactor) == -1 ) - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>Opening Acceptor\n</font>"), -1); - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) starting up server logging daemon\n</font>")); - - <font color=red>/* - 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. - */</font> - 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> -<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/001/page03.html b/docs/tutorials/001/page03.html deleted file mode 100644 index 5f45ca0826f..00000000000 --- a/docs/tutorials/001/page03.html +++ /dev/null @@ -1,215 +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> - -<hr> -<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> -<PRE> - -<font color=red>// $Id$</font> - - -<font color=blue>#ifndef</font> <font color=purple>_CLIENT_ACCEPTOR_H</font> -<font color=blue>#define</font> <font color=purple>_CLIENT_ACCEPTOR_H</font> - -<font color=red>/* - A SOCK_Acceptor knows how to accept socket connections. We'll use - one of those at the heart of our Logging_Acceptor. - */</font> -<font color=blue>#include</font> "<font color=green>ace/SOCK_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=red>/* - 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. - */</font> -<font color=blue>#include</font> "<font color=green>ace/Event_Handler.h</font>" - -<font color=red>/* - When a client connects, we'll create a Logging_Handler to deal with the - connection. Here, we bring in that declaration. - */</font> -<font color=blue>#include</font> "<font color=green>logger.h</font>" - -<font color=red>/* - Our Logging_Acceptor is derived from ACE_Event_Handler. That lets the - reactor treat our acceptor just like every other handler. - */</font> -class Logging_Acceptor : public ACE_Event_Handler -{ -public: - - <font color=red>/* - For this simple case we won't bother with either constructor or - destructor. In a real application you would certainly have them. - */</font> - - <font color=red>/* - 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. - */</font> - int open (const ACE_INET_Addr &_addr, ACE_Reactor * _reactor ) - { - <font color=red>/* - 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. - */</font> - if (this->peer_acceptor_.open (_addr, 1) == -1) - return -1; - - <font color=red>/* - Remember the reactor we're using. We'll need it later when we - create a client connection handler. - */</font> - reactor_ = _reactor; - - <font color=red>/* - 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. - */</font> - return _reactor->register_handler( this, <font color=#008888>ACE_Event_Handler::ACCEPT_MASK</font> ); - } - -private: - - <font color=red>/* - To provide multi-OS abstraction, ACE uses the concept of "<font color=green>handles</font>" 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. - */</font> - ACE_HANDLE get_handle (void) const - { - return this->peer_acceptor_.get_handle (); - } - - <font color=red>/* - When an accept request arrives, the reactor will invoke the handle_input() - callback. This is where we deal with the connection request. - */</font> - virtual int handle_input (ACE_HANDLE _handle) - { - <font color=red>/* - 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. - */</font> - ACE_UNUSED_ARG(_handle); - - <font color=red>/* - 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. - */</font> - Logging_Handler *svc_handler = new Logging_Handler; - - <font color=red>/* - To complete the connection, we invoke the accept() method call on - the acceptor object and provide it with the connection handler instance. - This transfers "<font color=green>ownership</font>" of the connection from the acceptor to the - connection handler. - */</font> - if (this->peer_acceptor_.accept (*svc_handler) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p</font>", "<font color=green>accept failed</font>"), -1); - - <font color=red>/* - 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(). - */</font> - if (svc_handler->open (reactor_) == -1) - svc_handler->close (); - - return 0; - } - -protected: - - <font color=red>/* - Our acceptor object instance - */</font> - ACE_SOCK_Acceptor peer_acceptor_; - - <font color=red>/* - A place to remember our reactor pointer - */</font> - ACE_Reactor * reactor_; -}; - -<font color=blue>#endif</font> <font color=red>/* _CLIENT_ACCEPTOR_H */</font> - -</PRE> -<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> -<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/001/page04.html b/docs/tutorials/001/page04.html deleted file mode 100644 index 079947a3b3a..00000000000 --- a/docs/tutorials/001/page04.html +++ /dev/null @@ -1,210 +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> - -<hr> -<P>Now we begin to look at the <A HREF="logger.h">logger</A> -object. - -<P> -<HR> -<PRE> - -<font color=red>// $Id$</font> - - -<font color=blue>#ifndef</font> <font color=purple>_CLIENT_HANDLER_H</font> -<font color=blue>#define</font> <font color=purple>_CLIENT_HANDLER_H</font> - -<font color=red>/* - A connection handler will also be derived from ACE_Event_Handler so that we - can register with a reactor. - */</font> -<font color=blue>#include</font> "<font color=green>ace/Event_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/INET_Addr.h</font>" - -<font color=red>/* - Since we're doing TCP/IP, we'll need a SOCK_Stream for the connection. - */</font> -<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>" - -class Logging_Handler : public ACE_Event_Handler -{ -public: - - <font color=red>/* - Like the acceptor, we're simple enough to avoid constructor and destructor. - */</font> - - <font color=red>/* - To open the client handler, we have to register ourselves with the reactor. - Notice that we don't have to "<font color=green>open</font>" our ACE_SOCK_Stream member variable. - Why? Because the call to the acceptor's accept() method took care of those - details for us. - */</font> - int open ( ACE_Reactor * _reactor ) - { - <font color=red>/* - Remember our reactor... - */</font> - reactor_ = _reactor; - - <font color=red>/* - 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. - */</font> - if (_reactor-> register_handler (this, <font color=#008888>ACE_Event_Handler::READ_MASK</font>) == -1) - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) can't register with reactor\n</font>"), -1); - return 0; - } - - <font color=red>/* - If we're explicitly closed we'll close our "<font color=green>file handle</font>". The net result - is to close the connection to the client and remove ourselves from the - reactor if we're registered - */</font> - int close (void) - { - return this->handle_close (ACE_INVALID_HANDLE, <font color=#008888>ACE_Event_Handler::RWE_MASK</font>); - } - - <font color=red>/* - 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. - */</font> - operator ACE_SOCK_Stream &() - { - return this->cli_stream_; - } - -protected: - - <font color=red>/* - Again, like the acceptor, we need to provide the connection handle to the reactor. - */</font> - ACE_HANDLE get_handle (void) const - { - return this->cli_stream_.get_handle (); - } - - <font color=red>/* - And here's the handle_input(). This is really the workhorse of the application. - */</font> - virtual int handle_input (ACE_HANDLE) - { - <font color=red>/* - Create and initialize a small receive buffer. - */</font> - char buf[128]; - memset(buf,0,sizeof(buf)); - - <font color=red>/* - 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. - */</font> - switch( this->cli_stream_.recv(buf,sizeof buf) ) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) %p bad read\n</font>", "<font color=green>client logger</font>"), -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) closing log daemon (fd = %d)\n</font>", - this->get_handle ()), -1); - default: - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) from client: %s</font>",buf)); - } - - return 0; - } - - <font color=red>/* - When handle_input() returns -1, we'll end up here. There are a few housekeeping - chores to handle. - */</font> - int handle_close (ACE_HANDLE, ACE_Reactor_Mask _mask) - { - <font color=red>/* - 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! - */</font> - reactor_->remove_handler(this,_mask|<font color=#008888>ACE_Event_Handler::DONT_CALL</font>); - - <font color=red>/* - Close the socket that we're connected to the client with. - */</font> - cli_stream_.close(); - - <font color=red>/* - Since we know we were dynamically allocated by the acceptor, now is a good - time to get rid of ourselves. - */</font> - delete this; - - return 0; - } - -protected: - - <font color=red>/* - Our peer connection. - */</font> - ACE_SOCK_Stream cli_stream_; - - <font color=red>/* - Our reactor (and our acceptor's reactor). - */</font> - ACE_Reactor * reactor_; -}; - -<font color=blue>#endif</font> <font color=red>/* _CLIENT_HANDLER_H */</font> - -</PRE> -<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> -<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/001/page05.html b/docs/tutorials/001/page05.html deleted file mode 100644 index 8725e1f410f..00000000000 --- a/docs/tutorials/001/page05.html +++ /dev/null @@ -1,54 +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> - -<hr> -<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 and I'll integrate it into the tutorial. - -<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> - -<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> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> 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 |