summaryrefslogtreecommitdiff
path: root/docs/tutorials/006
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/006')
-rw-r--r--docs/tutorials/006/006.dsp112
-rw-r--r--docs/tutorials/006/Makefile114
-rw-r--r--docs/tutorials/006/client_acceptor.h74
-rw-r--r--docs/tutorials/006/client_handler.cpp291
-rw-r--r--docs/tutorials/006/client_handler.h118
-rw-r--r--docs/tutorials/006/combine.shar508
-rw-r--r--docs/tutorials/006/page01.html62
-rw-r--r--docs/tutorials/006/page02.html145
-rw-r--r--docs/tutorials/006/page03.html112
-rw-r--r--docs/tutorials/006/page04.html153
-rw-r--r--docs/tutorials/006/page05.html348
-rw-r--r--docs/tutorials/006/page06.html46
-rw-r--r--docs/tutorials/006/server.cpp112
13 files changed, 0 insertions, 2195 deletions
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 57a90088d72..00000000000
--- a/docs/tutorials/006/Makefile
+++ /dev/null
@@ -1,114 +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
-
-
-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) hdr bodies *.pre *.pst
-
-UNSHAR : #
- sh combine.shar
-
-CLEAN : realclean
- $(RM) hdr bodies *.pre *.pst .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 4a50de72952..00000000000
--- a/docs/tutorials/006/client_acceptor.h
+++ /dev/null
@@ -1,74 +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 consistent 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 9ea01d64cda..00000000000
--- a/docs/tutorials/006/client_handler.cpp
+++ /dev/null
@@ -1,291 +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 *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
- client'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 ACE_*_cast macros 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 *) void_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.
-
- Note that if we're in thread-per-connection mode, open() is exited
- at this point. Furthermore, thread-per-connection mode does not
- use the reactor which means that handle_input() and it's fellows
- are not invoked. */
- if (acceptor->thread_per_connection ())
- return this->activate (THR_DETACHED);
-
- // ************************************************************************
- // From here on, we're doing the traditional reactor thing. If
- // you're operating in thread-per-connection mode, this code does
- // not apply.
- // ************************************************************************
-
- /* 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)
-{
- ACE_UNUSED_ARG (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.
-
- Again, this is not used if we're in thread-per-connection mode. */
-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[BUFSIZ];
-
- /* 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.
-
- Of course, this is only valid if we're in thread-per-connection
- mode. If we're using the reactor model, then svc() never comes
- into play. */
-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[BUFSIZ];
-
- // Forever...
- while( 1 )
- {
- /* Invoke the process() 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 e8d3695d37c..00000000000
--- a/docs/tutorials/006/client_handler.h
+++ /dev/null
@@ -1,118 +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 things 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 <handle> 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/combine.shar b/docs/tutorials/006/combine.shar
deleted file mode 100644
index 48385d7b563..00000000000
--- a/docs/tutorials/006/combine.shar
+++ /dev/null
@@ -1,508 +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-09-21 22:49 EDT by <jcej@chiroptera.tragus.org>.
-# Source directory was `/home/jcej/projects/ACE_wrappers/docs/tutorials/006'.
-#
-# Existing files will *not* be overwritten unless `-c' is specified.
-#
-# This shar contains:
-# length mode name
-# ------ ---------- ------------------------------------------
-# 605 -rw-rw-r-- hdr
-# 72 -rw-rw-r-- bodies
-# 1974 -rw-rw-r-- page01.pre
-# 252 -rw-rw-r-- page02.pre
-# 507 -rw-rw-r-- page03.pre
-# 227 -rw-rw-r-- page04.pre
-# 231 -rw-rw-r-- page05.pre
-# 697 -rw-rw-r-- page06.pre
-# 89 -rw-rw-r-- page02.pst
-# 168 -rw-rw-r-- page03.pst
-# 175 -rw-rw-r-- page04.pst
-# 1420 -rw-rw-r-- page05.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 _sh04795; 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="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
-X <META NAME="Author" CONTENT="James CE Johnson">
-X <META NAME="Description" CONTENT="A first step towards using ACE productively">
-X <TITLE>ACE Tutorial 006</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-X
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 006</FONT></B></CENTER>
-X
-<CENTER><B><FONT SIZE=+2>Creating a thread-per-connection server</FONT></B></CENTER>
-X
-X
-<P>
-<HR WIDTH="100%">
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-3289bf210fdf2f4b9d0a23b69c79a82f hdr
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`"
- test 605 -eq "$shar_count" ||
- $echo 'hdr:' 'original size' '605,' '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_acceptor.h
-client_handler.h
-client_handler.cpp
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-1f7383474ecfc75883354e67afaf1b3b bodies
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`"
- test 72 -eq "$shar_count" ||
- $echo 'bodies:' 'original size' '72,' '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>In this tutorial, we're going to extend Tutorial 5 to create a thread-per-connection
-server.&nbsp; This implementation will create a new thread for each client
-which connects to us.&nbsp; The ACE_Reactor is still used but only for
-accepting new connections.&nbsp; The Client_Handler objects won't be registered
-with the reactor.&nbsp; Instead, they'll be responsible for monitoring
-their peer() directly.
-<P>
-Abstract:<sup>*</sup>
-<ul>
-Here, we build a thread-per-connection simple server. This is the next
-step from a simple single-threaded server towards a multithreaded
-server.
-<p>
-We make use of the Strategy Pattern in this example.
-The ACE_Acceptor inherits form the ACE_Acceptor_Base class which
-facilitates us to implement various different concurrency strategies
-depending on whether the server is single-threaded or the server creates
-a new thread per connection. This also allows us to extend the
-capabilities of the server in the future by implementing a different
-strategy.
-<p>
-This information is passed on to the Client_Handler
-(remember ACE_Acceptor < Client_Handler, ACE_SOCK_ACCEPTOR > ?).
-The Client_Handler is an ACE_Svc_Handler as the Svc_Handler is a
-derivative of the Event_Handler and is associated with
-ACE_Sock_Stream. It is also derived form the ACE_Task class which allows
-us to have a thread per connection.
-<p>
-We incorporate the data processing in the svc() method, which will be
-called per thread for the thread-per-connection server.
-<p>
-Note that here all the Client_Handler objects aren't registered with the
-reactor. The Reactor is only used to accept client connections. Once a
-thread has been deicated per connection, the Client Handler object
-reponsible for that client connection now takes up the job of the
-reactor and handles future events.
-<p>
-Thus a simple, thread-per-connection server has been built which doesnt
-delve too deeply into mutli-threading issues.
-</ul>
-<font size=-1>* Abstract by Kirthika as always</font>
-SHAR_EOF
- $shar_touch -am 0118203099 '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'
-b66014851d6db1c8d89a07d024be2ecb page01.pre
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`"
- test 1974 -eq "$shar_count" ||
- $echo 'page01.pre:' 'original size' '1974,' '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>Again, we begin with <A HREF="server.cpp">server.cpp.</A>&nbsp; If you
-look closely you will see that the only difference between this and the
-Tutorial 5 implementation is a single comment.
-X
-<P>
-<HR WIDTH="100%"><FONT FACE="Arial,Helvetica"></FONT>
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-e9e18b8add5d997189fb16e67d1467b2 page02.pre
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`"
- test 252 -eq "$shar_count" ||
- $echo 'page02.pre:' 'original size' '252,' '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>In <A HREF="client_acceptor.h">client_acceptor.h</A>, we've extended
-our object just a bit.&nbsp; The primary reason is to allow us to select
-the previous single-threaded implementation or our new thread-per-connection
-implementation.&nbsp; Client_Acceptor itself doesn't use this information
-but makes it available to the Client_Handler objects it creates.&nbsp;
-If we wanted a single-strategy implementation, we would have made no changes
-to the Tutorial 5 version of this file.
-X
-<P>
-<HR WIDTH="100%">
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-40dd465ac9815a2c35375ccdbad0c98b page03.pre
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`"
- test 507 -eq "$shar_count" ||
- $echo 'page03.pre:' 'original size' '507,' '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><A HREF="client_handler.h">client_handler.h</A>
-shows a few more changes than the previous sources.&nbsp; The important
-change is the addition of a svc() method where our connection thread will
-exist.
-X
-<P>
-<HR WIDTH="100%">
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-8256aff03563fbc281403fc5bb970e69 page04.pre
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`"
- test 227 -eq "$shar_count" ||
- $echo 'page04.pre:' 'original size' '227,' '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><A HREF="client_handler.cpp">client_handler.cpp</A> exposes all the
-things I've been hinting at.&nbsp; Pay special attention to the decision
-made in open() as well as the bit of cleverness in svc().
-X
-<P>
-<HR WIDTH="100%">
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-08278c0477a109e107b680424bf70a9d page05.pre
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`"
- test 231 -eq "$shar_count" ||
- $echo 'page05.pre:' 'original size' '231,' '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' &&
-<P>That's it for Tutorial 6.&nbsp; 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.&nbsp; In
-Tutorial 7 we'll extend that again to allow a thread-pool choice in addition
-to the current two.
-X
-<P>For reference, here's the file list again:
-<UL>
-<LI>
-<A HREF="Makefile">Makefile</A></LI>
-X
-<LI>
-<A HREF="client_acceptor.h">client_acceptor.h</A></LI>
-X
-<LI>
-<A HREF="client_handler.cpp">client_handler.cpp</A></LI>
-X
-<LI>
-<A HREF="client_handler.h">client_handler.h</A></LI>
-X
-<LI>
-<A HREF="server.cpp">server.cpp</A></LI>
-X
-<LI>
-<A HREF="fix.Makefile">fix.Makefile</A></LI>
-</UL>
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-0adca372a5154acf673cc373d2acaf5a page06.pre
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`"
- test 697 -eq "$shar_count" ||
- $echo 'page06.pre:' 'original size' '697,' '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>Let's move along and see what happend to the Client_Acceptor.
-X
-<P>
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-0188a5ff7cacc123676e420ac5432207 page02.pst
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`"
- test 89 -eq "$shar_count" ||
- $echo 'page02.pst:' 'original size' '89,' '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%">
-X
-<P>Ok, so far we haven't done much to change our concurrency strategy.&nbsp;
-Let's move on to the Client_Handler and see if it has changed any.
-X
-<P>
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-7743577254d06f5848b5e50f3b6c3014 page03.pst
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pst'`"
- test 168 -eq "$shar_count" ||
- $echo 'page03.pst:' 'original size' '168,' '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>So... we've added a svc() method and alluded to changes in open().&nbsp;
-Let's move on to the object definition and see what all the fuss is about.
-X
-<P>
-SHAR_EOF
- $shar_touch -am 0118202399 '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'
-dfe0897cc3f000b69c16c87dd1596281 page04.pst
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`"
- test 175 -eq "$shar_count" ||
- $echo 'page04.pst:' 'original size' '175,' 'current size' "$shar_count!"
- fi
-fi
-# ============= page05.pst ==============
-if test -f 'page05.pst' && test "$first_param" != -c; then
- $echo 'x -' SKIPPING 'page05.pst' '(file already exists)'
-else
- $echo 'x -' extracting 'page05.pst' '(text)'
- sed 's/^X//' << 'SHAR_EOF' > 'page05.pst' &&
-<HR WIDTH="100%">
-<P>
-X Did you notice the <i>THR_DETACHED</i> flag on the call to
-X <i>activate()</i>? Threads, like any system resource, are a
-X limited resource. Unless we intend to <i>join()</i> or
-X <i>wait()</i> for the new thread later, we want use THR_DETACHED
-X so that we don't cause a leak. In fact, in most cases, you'll
-X want to specify THR_DETACHED because it's just easier.
-<p>
-X Another handy flag for use with <i>activate()</i> is
-X <i>THR_NEW_LWP</i>. That's short for <i>Light Weight
-X Process</i>. If you've got a multiprocessor, this flag will
-X allocate a new schedulable process and decrease the odds of your
-X threads all fighting for the same process. Of course, if you
-X have a uni-processor, it will neither help nor hurt. Since I
-X developed these on a uni-processor, I've been a bit inconsistent
-X in the use of <i>THR_NEW_LWP</i>.
-X
-<P>Well, that's it!&nbsp; After all the talk &amp; the hype, you would
-have expected it to be more difficult to create a multi-threaded server.&nbsp;
-Surprise!&nbsp; It really is that easy.&nbsp; You still have to handle
-contention issues which we haven't addressed here and that is a rather
-nasty topic.&nbsp; Still, for the simple case, this is all you have to
-do.
-X
-<P>The next page is the last for this tutorial.&nbsp; Head on over there
-&amp; we'll round up the file list one last time.
-X
-<P>
-SHAR_EOF
- $shar_touch -am 0921222699 'page05.pst' &&
- chmod 0664 'page05.pst' ||
- $echo 'restore of' 'page05.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 'page05.pst:' 'MD5 check failed'
-fab2e03eb2f115f89a58d70be291e87e page05.pst
-SHAR_EOF
- else
- shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pst'`"
- test 1420 -eq "$shar_count" ||
- $echo 'page05.pst:' 'original size' '1420,' 'current size' "$shar_count!"
- fi
-fi
-rm -fr _sh04795
-exit 0
diff --git a/docs/tutorials/006/page01.html b/docs/tutorials/006/page01.html
deleted file mode 100644
index 3ff14911f04..00000000000
--- a/docs/tutorials/006/page01.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!-- $Id$ -->
-<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.&nbsp; This implementation will create a new thread for each client
-which connects to us.&nbsp; The ACE_Reactor is still used but only for
-accepting new connections.&nbsp; The Client_Handler objects won't be registered
-with the reactor.&nbsp; Instead, they'll be responsible for monitoring
-their peer() directly.
-<P>
-Abstract:<sup>*</sup>
-<ul>
-Here, we build a thread-per-connection simple server. This is the next
-step from a simple single-threaded server towards a multithreaded
-server.
-<p>
-We make use of the Strategy Pattern in this example.
-The ACE_Acceptor inherits form the ACE_Acceptor_Base class which
-facilitates us to implement various different concurrency strategies
-depending on whether the server is single-threaded or the server creates
-a new thread per connection. This also allows us to extend the
-capabilities of the server in the future by implementing a different
-strategy.
-<p>
-This information is passed on to the Client_Handler
-(remember ACE_Acceptor < Client_Handler, ACE_SOCK_ACCEPTOR > ?).
-The Client_Handler is an ACE_Svc_Handler as the Svc_Handler is a
-derivative of the Event_Handler and is associated with
-ACE_Sock_Stream. It is also derived form the ACE_Task class which allows
-us to have a thread per connection.
-<p>
-We incorporate the data processing in the svc() method, which will be
-called per thread for the thread-per-connection server.
-<p>
-Note that here all the Client_Handler objects aren't registered with the
-reactor. The Reactor is only used to accept client connections. Once a
-thread has been deicated per connection, the Client Handler object
-reponsible for that client connection now takes up the job of the
-reactor and handles future events.
-<p>
-Thus a simple, thread-per-connection server has been built which doesnt
-delve too deeply into mutli-threading issues.
-</ul>
-<font size=-1>* Abstract by Kirthika as always</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/006/page02.html b/docs/tutorials/006/page02.html
deleted file mode 100644
index e56c466767d..00000000000
--- a/docs/tutorials/006/page02.html
+++ /dev/null
@@ -1,145 +0,0 @@
-<!-- $Id$ -->
-<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>&nbsp; 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>
-<PRE>
-<font color=red>// $Id$</font>
-
-<font color=red>/* 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 "<font color=green>real work</font>". */</font>
-
-<font color=blue>#include</font> "<font color=green>client_acceptor.h</font>"
-
-<font color=red>/* 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. */</font>
-
-static sig_atomic_t finished = 0;
-extern "<font color=green>C</font>" void handler (int)
-{
- finished = 1;
-}
-
-<font color=red>/* 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. */</font>
-
-static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
-
-<font color=red>/* 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. */</font>
-
-int
-main (int argc, char *argv[])
-{
- <font color=red>/* 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. */</font>
- ACE_Reactor reactor;
-
- <font color=red>/* 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.) */</font>
- Client_Acceptor peer_acceptor;
-
- <font color=red>/* 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 "<font color=green>well known</font>" 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. */</font>
- if (peer_acceptor.open (ACE_INET_Addr (PORT),
- &reactor) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- "<font color=green>%p\n</font>",
- "<font color=green>open</font>"),
- -1);
-
- <font color=red>/* As with Tutorial 5, we know that we're now registered with our
- reactor so we don't have to mess with that step. */</font>
-
- <font color=red>/* 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 "<font color=green>real</font>" work. Our simple
- flag-setter doesn't justify deriving from ACE_Event_Handler and
- providing a callback function though. */</font>
- ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);
-
- <font color=red>/* 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. */</font>
- ACE_DEBUG ((LM_DEBUG,
- "<font color=green>(%P|%t) starting up server daemon\n</font>"));
-
- <font color=red>/* This will loop "<font color=green>forever</font>" 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 &lt;i>restart&lt;/i> flag on
- the open() method of ACE_Reactor if you're interested.) */</font>
- while (!finished)
- reactor.handle_events ();
-
- ACE_DEBUG ((LM_DEBUG,
- "<font color=green>(%P|%t) shutting down server daemon\n</font>"));
-
- return 0;
-}
-
-<font color=blue>#if !defined</font>(<font color=purple>ACE_HAS_GNU_REPO</font>)
-<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>)
-template class ACE_Acceptor &lt;Client_Handler, ACE_SOCK_ACCEPTOR>;
-template class ACE_Svc_Handler&lt;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 &lt;Client_Handler, ACE_SOCK_ACCEPTOR>
-<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Svc_Handler&lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH>
-<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font>
-<font color=blue>#endif</font> <font color=red>/* ACE_HAS_GNU_REPO */</font>
-</PRE>
-<HR WIDTH="100%">
-
-<P>Let's move along and see what happend to the Client_Acceptor.
-
-<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/006/page03.html b/docs/tutorials/006/page03.html
deleted file mode 100644
index 1c202720321..00000000000
--- a/docs/tutorials/006/page03.html
+++ /dev/null
@@ -1,112 +0,0 @@
-<!-- $Id$ -->
-<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.&nbsp; The primary reason is to allow us to select
-the previous single-threaded implementation or our new thread-per-connection
-implementation.&nbsp; Client_Acceptor itself doesn't use this information
-but makes it available to the Client_Handler objects it creates.&nbsp;
-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%">
-<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>/* The ACE_Acceptor&lt;> template lives in the ace/Acceptor.h header
- file. You'll find a very consistent 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. */</font>
-
-<font color=blue>#include</font> "<A HREF="../../../ace/Acceptor.h">ace/Acceptor.h</A>"
-
-<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>)
-<font color=blue># pragma</font> <font color=purple>once</font>
-<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>
-
-<font color=red>/* Since we want to work with sockets, we'll need a SOCK_Acceptor to
- allow the clients to connect to us. */</font>
-<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Acceptor.h">ace/SOCK_Acceptor.h</A>"
-
-<font color=red>/* The Client_Handler object we develop will be used to handle clients
- once they're connected. The ACE_Acceptor&lt;> 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. */</font>
-<font color=blue>#include</font> "<font color=green>client_handler.h</font>"
-
-<font color=red>/* Parameterize the ACE_Acceptor&lt;> 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&lt;> was available. You'll
- get spoiled using the ACE templates because they take away a lot of
- the tedious details! */</font>
-typedef ACE_Acceptor &lt;Client_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor_Base;
-
-<font color=red>/* Here, we use the parameterized ACE_Acceptor&lt;> 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. */</font>
-class Client_Acceptor : public Client_Acceptor_Base
-{
-public:
- <font color=red>/*
- This is always a good idea. If nothing else, it makes your code more
- orthogonal no matter what baseclasses your objects have.
- */</font>
- typedef Client_Acceptor_Base inherited;
-
- <font color=red>/*
- 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.
- */</font>
- Client_Acceptor (int thread_per_connection = 1)
- : thread_per_connection_ (thread_per_connection)
- {
- }
-
- <font color=red>/* 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. */</font>
- int thread_per_connection (void)
- {
- return this->thread_per_connection_;
- }
-
-protected:
- int thread_per_connection_;
-};
-
-<font color=blue>#endif</font> <font color=red>/* CLIENT_ACCEPTOR_H */</font>
-</PRE>
-<HR WIDTH="100%">
-
-<P>Ok, so far we haven't done much to change our concurrency strategy.&nbsp;
-Let's move on to the Client_Handler and see if it has changed any.
-
-<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/006/page04.html b/docs/tutorials/006/page04.html
deleted file mode 100644
index a43304af2e4..00000000000
--- a/docs/tutorials/006/page04.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!-- $Id$ -->
-<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.&nbsp; The important
-change is the addition of a svc() method where our connection thread will
-exist.
-
-<P>
-<HR WIDTH="100%">
-<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>/* 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.
-
- */</font>
-
-<font color=blue>#include</font> "<A HREF="../../../ace/Svc_Handler.h">ace/Svc_Handler.h</A>"
-
-<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>)
-<font color=blue># pragma</font> <font color=purple>once</font>
-<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>
-
-<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Stream.h">ace/SOCK_Stream.h</A>"
-
-<font color=red>/* Another feature of ACE_Svc_Handler is it's ability to present the
- ACE_Task&lt;> 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 things ACE_NULL_SYNCH exists for but
- stick around for Tutorial 7 and pay special attention to the
- Thread_Pool object there for an explanation. */</font>
-class Client_Handler : public ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH>
-{
-public:
- typedef ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH> inherited;
-
- <font color=red>// Constructor...</font>
- Client_Handler (void);
-
- <font color=red>/* 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. */</font>
- void destroy (void);
-
- <font color=red>/* 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&lt;> 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&lt;>* but since ACE_Event_Handler is generic, that would
- tie it too closely to the ACE_Acceptor&lt;> set of objects. In our
- definition of open() you'll see how we get around that. */</font>
- int open (void *acceptor);
-
- <font color=red>/* When an ACE_Task&lt;> 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. */</font>
- int close (u_long flags = 0);
-
- <font color=red>/* 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 &lt;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! */</font>
- virtual int handle_close (ACE_HANDLE handle = ACE_INVALID_HANDLE,
- ACE_Reactor_Mask mask = <font color=#008888>ACE_Event_Handler::ALL_EVENTS_MASK</font>);
-
-protected:
-
- <font color=red>/* 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. */</font>
- int svc (void);
-
- <font color=red>/* 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&lt;> 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 &lt;handle> would
- be important to us for reading the client's data. */</font>
- int handle_input (ACE_HANDLE handle);
-
- <font color=red>/* 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. */</font>
- int process (char *rdbuf, int rdbuf_len);
-
- <font color=red>/* 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. */</font>
- ~Client_Handler (void);
-};
-
-<font color=blue>#endif</font> <font color=red>/* CLIENT_HANDLER_H */</font>
-</PRE>
-<HR WIDTH="100%">
-
-<P>So... we've added a svc() method and alluded to changes in open().&nbsp;
-Let's move on to the object definition and see what all the fuss is about.
-
-<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/006/page05.html b/docs/tutorials/006/page05.html
deleted file mode 100644
index af803d9a54a..00000000000
--- a/docs/tutorials/006/page05.html
+++ /dev/null
@@ -1,348 +0,0 @@
-<!-- $Id$ -->
-<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.cpp">client_handler.cpp</A> exposes all the
-things I've been hinting at.&nbsp; Pay special attention to the decision
-made in open() as well as the bit of cleverness in svc().
-
-<P>
-<HR WIDTH="100%">
-<PRE>
-<font color=red>// $Id$</font>
-
-<font color=red>/* 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. */</font>
-<font color=blue>#include</font> "<font color=green>client_acceptor.h</font>"
-<font color=blue>#include</font> "<font color=green>client_handler.h</font>"
-
-<font color=red>/* 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... */</font>
-<font color=#008888>Client_Handler::Client_Handler</font> (void)
-{
-}
-
-<font color=red>/* 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. */</font>
-<font color=#008888>Client_Handler::~Client_Handler</font> (void)
-{
-}
-
-<font color=red>/* 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. */</font>
-void
-<font color=#008888>Client_Handler::destroy</font> (void)
-{
- <font color=red>/* 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! */</font>
- this->reactor ()->remove_handler (this,
- <font color=#008888>ACE_Event_Handler::READ_MASK</font>
- | <font color=#008888>ACE_Event_Handler::DONT_CALL</font>);
-
- <font color=red>/* 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. */</font>
- delete this;
-}
-
-<font color=red>/* 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... */</font>
-int
-<font color=#008888>Client_Handler::open</font> (void *void_acceptor)
-{
- <font color=red>/* 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. */</font>
- ACE_INET_Addr addr;
-
- <font color=red>/* 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
- client'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. */</font>
- if (this->peer ().get_remote_addr (addr) == -1)
- return -1;
-
- <font color=red>/* Convert the void* to a Client_Acceptor*. You should probably use
- those fancy ACE_*_cast macros 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. */</font>
- Client_Acceptor *acceptor = (Client_Acceptor *) void_acceptor;
-
- <font color=red>/* 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.
-
- Note that if we're in thread-per-connection mode, open() is exited
- at this point. Furthermore, thread-per-connection mode does not
- use the reactor which means that handle_input() and it's fellows
- are not invoked. */</font>
- if (acceptor->thread_per_connection ())
- return this->activate (THR_DETACHED);
-
- <font color=red>// ************************************************************************</font>
- <font color=red>// From here on, we're doing the traditional reactor thing. If</font>
- <font color=red>// you're operating in thread-per-connection mode, this code does</font>
- <font color=red>// not apply.</font>
- <font color=red>// ************************************************************************</font>
-
- <font color=red>/* Our reactor reference will be set when we register ourselves but
- I decided to go ahead and set it here. No good reason really... */</font>
- this->reactor (acceptor->reactor ());
-
- <font color=red>/* 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. */</font>
- if (this->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);
-
- <font color=red>/* 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. */</font>
- ACE_DEBUG ((LM_DEBUG,
- "<font color=green>(%P|%t) connected with %s\n</font>", addr.get_host_name ()));
-
- <font color=red>/* Always return zero on success. */</font>
- return 0;
-}
-
-<font color=red>/* 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. */</font>
-int
-<font color=#008888>Client_Handler::close</font>(u_long flags)
-{
- ACE_UNUSED_ARG (flags);
-
- <font color=red>/* 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. */</font>
- this->destroy ();
-
- <font color=red>/* 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! */</font>
- return 0;
-}
-
-<font color=red>/* 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.
-
- Again, this is not used if we're in thread-per-connection mode. */</font>
-int
-<font color=#008888>Client_Handler::handle_input</font> (ACE_HANDLE handle)
-{
- <font color=red>/* Some compilers don't like it when you fail to use a parameter.
- This macro will keep 'em quiet for you. */</font>
- ACE_UNUSED_ARG (handle);
-
- <font color=red>/* 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. */</font>
- char buf[BUFSIZ];
-
- <font color=red>/* 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. */</font>
- return this->process (buf, sizeof (buf));
-}
-
-<font color=red>/* 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. */</font>
-int
-<font color=#008888>Client_Handler::handle_close</font> (ACE_HANDLE handle,
- ACE_Reactor_Mask mask)
-{
- ACE_UNUSED_ARG (handle);
- ACE_UNUSED_ARG (mask);
-
- this->destroy ();
- return 0;
-}
-
-<font color=red>/* The ACE_Svc_Handler&lt;> is ultimately derived from ACE_Task&lt;>. 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.
-
- Of course, this is only valid if we're in thread-per-connection
- mode. If we're using the reactor model, then svc() never comes
- into play. */</font>
-int
-<font color=#008888>Client_Handler::svc</font>(void)
-{
- <font color=red>/* 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(). */</font>
- char buf[BUFSIZ];
-
- <font color=red>// Forever...</font>
- while( 1 )
- {
- <font color=red>/* Invoke the process() 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. */</font>
- if (this->process(buf, sizeof (buf)) == -1)
- return -1;
- }
-
- return 0;
-}
-
-<font color=red>/* 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. */</font>
-int
-<font color=#008888>Client_Handler::process</font> (char *rdbuf,
- int rdbuf_len)
-{
- <font color=red>/* 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. */</font>
- switch (this->peer ().recv (rdbuf, rdbuf_len))
- {
- case -1:
- ACE_ERROR_RETURN ((LM_ERROR,
- "<font color=green>(%P|%t) %p bad read\n</font>",
- "<font color=green>client</font>"),
- -1);
- case 0:
- ACE_ERROR_RETURN ((LM_ERROR,
- "<font color=green>(%P|%t) closing daemon (fd = %d)\n</font>",
- this->get_handle ()),
- -1);
- default:
- ACE_DEBUG ((LM_DEBUG,
- "<font color=green>(%P|%t) from client: %s</font>",
- rdbuf));
- }
-
- return 0;
-}
-</PRE>
-<HR WIDTH="100%">
-<P>
- Did you notice the <i>THR_DETACHED</i> flag on the call to
- <i>activate()</i>? Threads, like any system resource, are a
- limited resource. Unless we intend to <i>join()</i> or
- <i>wait()</i> for the new thread later, we want use THR_DETACHED
- so that we don't cause a leak. In fact, in most cases, you'll
- want to specify THR_DETACHED because it's just easier.
-<p>
- Another handy flag for use with <i>activate()</i> is
- <i>THR_NEW_LWP</i>. That's short for <i>Light Weight
- Process</i>. If you've got a multiprocessor, this flag will
- allocate a new schedulable process and decrease the odds of your
- threads all fighting for the same process. Of course, if you
- have a uni-processor, it will neither help nor hurt. Since I
- developed these on a uni-processor, I've been a bit inconsistent
- in the use of <i>THR_NEW_LWP</i>.
-
-<P>Well, that's it!&nbsp; After all the talk &amp; the hype, you would
-have expected it to be more difficult to create a multi-threaded server.&nbsp;
-Surprise!&nbsp; It really is that easy.&nbsp; You still have to handle
-contention issues which we haven't addressed here and that is a rather
-nasty topic.&nbsp; Still, for the simple case, this is all you have to
-do.
-
-<P>The next page is the last for this tutorial.&nbsp; Head on over there
-&amp; we'll round up the file list one last time.
-
-<P>
-<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/006/page06.html b/docs/tutorials/006/page06.html
deleted file mode 100644
index 522318b436c..00000000000
--- a/docs/tutorials/006/page06.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!-- $Id$ -->
-<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>That's it for Tutorial 6.&nbsp; 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.&nbsp; 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="../online-tutorials.html">Tutorial Index</A>] </CENTER>
diff --git a/docs/tutorials/006/server.cpp b/docs/tutorials/006/server.cpp
deleted file mode 100644
index fd3a18d9d28..00000000000
--- a/docs/tutorials/006/server.cpp
+++ /dev/null
@@ -1,112 +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 */