summaryrefslogtreecommitdiff
path: root/docs/tutorials/007
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/007')
-rw-r--r--docs/tutorials/007/007.dsp124
-rw-r--r--docs/tutorials/007/Makefile101
-rw-r--r--docs/tutorials/007/client_acceptor.cpp67
-rw-r--r--docs/tutorials/007/client_acceptor.h141
-rw-r--r--docs/tutorials/007/client_handler.cpp239
-rw-r--r--docs/tutorials/007/client_handler.h172
-rw-r--r--docs/tutorials/007/page01.html33
-rw-r--r--docs/tutorials/007/page02.html197
-rw-r--r--docs/tutorials/007/page03.html263
-rw-r--r--docs/tutorials/007/page04.html133
-rw-r--r--docs/tutorials/007/page05.html208
-rw-r--r--docs/tutorials/007/page06.html272
-rw-r--r--docs/tutorials/007/page07.html197
-rw-r--r--docs/tutorials/007/page08.html537
-rw-r--r--docs/tutorials/007/page09.html85
-rw-r--r--docs/tutorials/007/server.cpp119
-rw-r--r--docs/tutorials/007/thread_pool.cpp277
-rw-r--r--docs/tutorials/007/thread_pool.h102
18 files changed, 0 insertions, 3267 deletions
diff --git a/docs/tutorials/007/007.dsp b/docs/tutorials/007/007.dsp
deleted file mode 100644
index d069843ec50..00000000000
--- a/docs/tutorials/007/007.dsp
+++ /dev/null
@@ -1,124 +0,0 @@
-# Microsoft Developer Studio Project File - Name="007" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=007 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "007.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "007.mak" CFG="007 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "007 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "007 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "007 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "007 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "007 - Win32 Release"
-# Name "007 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\client_acceptor.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\client_handler.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\thread_pool.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\client_acceptor.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\client_handler.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\thread_pool.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/007/Makefile b/docs/tutorials/007/Makefile
deleted file mode 100644
index 8e430900570..00000000000
--- a/docs/tutorials/007/Makefile
+++ /dev/null
@@ -1,101 +0,0 @@
-#----------------------------------------------------------------------------
-# $Id$
-#----------------------------------------------------------------------------
-
-#----------------------------------------------------------------------------
-# Local macros
-#----------------------------------------------------------------------------
-
-# You can generally find a Makefile in the ACE examples, tests or the library
-# itself that will satisfy our application needs. This one was taken from
-# one of the examples.
-
- # Define the name of the binary we want to create. There has to be
- # a CPP file $(BIN).cpp but it doesn't necessarily have to have your
- # main() in it. Most of the time, though, it will.
-BIN = server
-
- # Few applications will have a single source file. We use the FILES
- # macro to build up a list of additional files to compile. Notice
- # that we leave off the extension just as with BIN
-FILES =
-FILES += client_handler
-FILES += client_acceptor
-FILES += thread_pool
-
- # The BUILD macro is used by the ACE makefiles. Basically, it tells
- # the system what to build. I don't really know what VBIN is other
- # than it is constructed from the value of BIN. Just go with it...
-BUILD = $(VBIN)
-
- # Here we use some GNU make extensions to build the SRC macro. Basically,
- # we're just adding .cpp to the value of BIN and for each entry of the
- # FILES macro.
-SRC = $(addsuffix .cpp,$(BIN)) $(addsuffix .cpp,$(FILES))
-
- # This is used by my Indent target below. It's not a part of standard
- # ACE and you don't need it yourself.
-HDR = *.h
-
-#----------------------------------------------------------------------------
-# Include macros and targets
-#----------------------------------------------------------------------------
-
- # This is where the real power lies! These included makefile components
- # are similar to the C++ templates in ACE. That is, they do a tremendous
- # amount of work for you and all you have to do is include them.
- # As a matter of fact, in our project, I created a single file named
- # "app.mk" that includes all of these. Our project makefiles then just
- # need to include app.mk to get everything they need.
-
-include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
-include $(ACE_ROOT)/include/makeinclude/macros.GNU
-include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
-include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
-include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
-include $(ACE_ROOT)/include/makeinclude/rules.local.GNU
-
-#----------------------------------------------------------------------------
-# Local targets
-#----------------------------------------------------------------------------
-
- # Sometimes I like to reformat my code to make it more readable. This is
- # more useful for the comments than anything else. Unfortunately, the
- # "indent" program doesn't quite grok C++ so I have to post-process it's
- # output just a bit.
-Indent : #
- for i in $(SRC) $(HDR) ; do \
- indent -npsl -l80 -fca -fc1 -cli0 -cdb < $$i | \
- sed -e 's/: :/::/g' \
- -e 's/^.*\(public:\)/\1/' \
- -e 's/^.*\(protected:\)/\1/' \
- -e 's/^.*\(private:\)/\1/' \
- -e 's/:\(public\)/ : \1/' \
- -e 's/:\(protected\)/ : \1/' \
- -e 's/:\(private\)/ : \1/' \
- > $$i~ ;\
- mv $$i~ $$i ;\
- done
-
- # One of the targets in the ACE makefiles is "depend". It will invoke
- # your compiler in a way that will generate a list of dependencies for
- # you. This is a great thing! Unfortunately, it puts all of that mess
- # directly into the Makefile. I prefer my Makefile to stay clean and
- # uncluttered. The perl script referenced here pulls the dependency
- # stuff back out of the Makefile and into a file ".depend" which we then
- # include just like the makefile components above.
-Depend : depend
- perl ../fix.Makefile
-
-.depend : #
- touch .depend
-
-#----------------------------------------------------------------------------
-# Dependencies
-#----------------------------------------------------------------------------
-
- # Don't put anything below here. Between the "depend" target and fix.Makefile
- # it's guaranteed to be lost!
-
- # This is inserted by the fix.Makefile script
-include .depend
diff --git a/docs/tutorials/007/client_acceptor.cpp b/docs/tutorials/007/client_acceptor.cpp
deleted file mode 100644
index 6cc90612558..00000000000
--- a/docs/tutorials/007/client_acceptor.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-
-// $Id$
-
-#include "client_acceptor.h"
-
-/*
- Construct ourselves with the chosen concurrency strategy. Notice that we also
- set our Thread_Pool reference to our private instance.
- */
-Client_Acceptor::Client_Acceptor( int _concurrency )
- : concurrency_(_concurrency)
- ,the_thread_pool_(private_thread_pool_)
-{
-}
-
-/*
- Construct ourselves with a reference to somebody else' Thread_Pool. Obvioulsy
- our concurrency strategy is "thread_pool_" at this point.
- */
-Client_Acceptor::Client_Acceptor( Thread_Pool & _thread_pool )
- : concurrency_(thread_pool_)
- ,the_thread_pool_(_thread_pool)
-{
-}
-
-/*
- When we're destructed, we may need to cleanup after ourselves. If we're running
- with a thread pool that we own, it is up to us to close it down.
- */
-Client_Acceptor::~Client_Acceptor( void )
-{
- if( this->concurrency() == thread_pool_ && thread_pool_is_private() )
- {
- thread_pool()->close();
- }
-}
-
-/*
- Similar to the destructor (and close() below) it is necessary for us to open the
- thread pool in some circumstances.
-
- Notice how we delegate most of the open() work to the open() method of our baseclass.
- */
-int Client_Acceptor::open( const ACE_INET_Addr & _addr, ACE_Reactor * _reactor, int _pool_size )
-{
- if( this->concurrency() == thread_pool_ && thread_pool_is_private() )
- {
- thread_pool()->open(_pool_size);
- }
-
- return inherited::open(_addr,_reactor);
-}
-
-/*
- Here again we find that we have to manage the thread pool. Like open() we also delegate
- the other work to our baseclass.
- */
-int Client_Acceptor::close(void)
-{
- if( this->concurrency() == thread_pool_ && thread_pool_is_private() )
- {
- thread_pool()->close();
- }
-
- return inherited::close();
-}
-
diff --git a/docs/tutorials/007/client_acceptor.h b/docs/tutorials/007/client_acceptor.h
deleted file mode 100644
index 82c761879ea..00000000000
--- a/docs/tutorials/007/client_acceptor.h
+++ /dev/null
@@ -1,141 +0,0 @@
-
-// $Id$
-
-#ifndef CLIENT_ACCEPTOR_H
-#define CLIENT_ACCEPTOR_H
-
-/*
- The ACE_Acceptor<> template lives in the ace/Acceptor.h header file. You'll
- find a very consitent naming convention between the ACE objects and the
- headers where they can be found. In general, the ACE object ACE_Foobar will
- be found in ace/Foobar.h.
- */
-
-#include "ace/Acceptor.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-/*
- Since we want to work with sockets, we'll need a SOCK_Acceptor to allow the
- clients to connect to us.
- */
-#include "ace/SOCK_Acceptor.h"
-
-/*
- The Client_Handler object we develop will be used to handle clients once
- they're connected. The ACE_Acceptor<> template's first parameter requires
- such an object. In some cases, you can get by with just a forward
- declaration on the class, in others you have to have the whole thing.
- */
-#include "client_handler.h"
-
-/*
- Parameterize the ACE_Acceptor<> such that it will listen for socket
- connection attempts and create Client_Handler objects when they happen. In
- Tutorial 001, we wrote the basic acceptor logic on our own before we
- realized that ACE_Acceptor<> was available. You'll get spoiled using the
- ACE templates because they take away a lot of the tedious details!
- */
-typedef ACE_Acceptor < Client_Handler, ACE_SOCK_ACCEPTOR > Client_Acceptor_Base;
-
-#include "thread_pool.h"
-
-/*
- This time we've added quite a bit more to our acceptor. In addition to
- providing a choice of concurrency strategies, we also maintain a Thread_Pool
- object in case that strategy is chosen. The object still isn't very complex
- but it's come a long way from the simple typedef we had in Tutorial 5.
-
- Why keep the thread pool as a member? If we go back to the inetd concept
- you'll recall that we need several acceptors to make that work. We may have
- a situation in which our different client types requre different resources.
- That is, we may need a large thread pool for some client types and a smaller
- one for others. We could share a pool but then the client types may have
- undesirable impact on one another.
-
- Just in case you do want to share a single thread pool, there is a constructor
- below that will let you do that.
- */
-class Client_Acceptor : public Client_Acceptor_Base
-{
-public:
- typedef Client_Acceptor_Base inherited;
-
- /*
- Now that we have more than two strategies, we need more than a boolean
- to tell us what we're using. A set of enums is a good choice because
- it allows us to use named values. Another option would be a set of
- static const integers.
- */
- enum concurrency_t
- {
- single_threaded_,
- thread_per_connection_,
- thread_pool_
- };
-
- /*
- The default constructor allows the programmer to choose the concurrency
- strategy. Since we want to focus on thread-pool, that's what we'll use
- if nothing is specified.
- */
- Client_Acceptor( int _concurrency = thread_pool_ );
-
- /*
- Another option is to construct the object with an existing thread pool.
- The concurrency strategy is pretty obvious at that point.
- */
- Client_Acceptor( Thread_Pool & _thread_pool );
-
- /*
- Our destructor will take care of shutting down the thread-pool
- if applicable.
- */
- ~Client_Acceptor( void );
-
- /*
- Open ourselves and register with the given reactor. The thread pool size
- can be specified here if you want to use that concurrency strategy.
- */
- int open( const ACE_INET_Addr & _addr, ACE_Reactor * _reactor,
- int _pool_size = Thread_Pool::default_pool_size_ );
-
- /*
- Close ourselves and our thread pool if applicable
- */
- int close(void);
-
- /*
- What is our concurrency strategy?
- */
- int concurrency(void)
- { return this->concurrency_; }
-
- /*
- Give back a pointer to our thread pool. Our Client_Handler objects
- will need this so that their handle_input() methods can put themselves
- into the pool. Another alternative would be a globally accessible
- thread pool. ACE_Singleton<> is a way to achieve that.
- */
- Thread_Pool * thread_pool(void)
- { return & this->the_thread_pool_; }
-
- /*
- Since we can be constructed with a Thread_Pool reference, there are times
- when we need to know if the thread pool we're using is ours or if we're
- just borrowing it from somebody else.
- */
- int thread_pool_is_private(void)
- { return &the_thread_pool_ == &private_thread_pool_; }
-
-protected:
- int concurrency_;
-
- Thread_Pool private_thread_pool_;
-
- Thread_Pool & the_thread_pool_;
-};
-
-#endif // CLIENT_ACCEPTOR_H
diff --git a/docs/tutorials/007/client_handler.cpp b/docs/tutorials/007/client_handler.cpp
deleted file mode 100644
index 647739e34e2..00000000000
--- a/docs/tutorials/007/client_handler.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-
-// $Id$
-
-/*
- Since this is the third time we've seen most of this, I'm going to strip out almost
- all of the comments that you've already seen. That way, you can concentrate on the
- new items.
- */
-
-#include "client_acceptor.h"
-#include "client_handler.h"
-
-/*
- We're going to be registering and unregistering a couple of times. To make sure that
- we use the same flags every time, I've created these handy macros.
- */
-#define REGISTER_MASK ACE_Event_Handler::READ_MASK
-#define REMOVE_MASK (ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL)
-
-/*
- Our constructor still doesn't really do anything. We simply initialize the acceptor
- pointer to "null" and get our current thread id. The static self() method of ACE_Thread
- will return you a thread id native to your platform.
- */
-Client_Handler::Client_Handler (void)
- : client_acceptor_(0)
- ,creator_(ACE_Thread::self())
-{
-}
-
-Client_Handler::~Client_Handler (void)
-{
- this->peer().close();
-}
-
-/*
- Query our acceptor for the concurrency strategy. Notice that we don't bother
- to check that our acceptor pointer is valid. That is proably a bad idea...
- */
-int Client_Handler::concurrency(void)
-{
- return this->client_acceptor()->concurrency();
-}
-
-/*
- And here we ask the acceptor about the thread pool.
- */
-Thread_Pool * Client_Handler::thread_pool(void)
-{
- return this->client_acceptor()->thread_pool();
-}
-
-/*
- Back to our open() method. This is straight out of Tutorial 6. There's
- nothing additional here for the thread-pool implementation.
- */
-int Client_Handler::open (void *_acceptor)
-{
- client_acceptor( (Client_Acceptor *) _acceptor );
-
- if( concurrency() == Client_Acceptor::thread_per_connection_ )
- {
- return this->activate();
- }
-
- this->reactor (client_acceptor()->reactor ());
-
- ACE_INET_Addr addr;
-
- if (this->peer ().get_remote_addr (addr) == -1)
- {
- return -1;
- }
-
- if (this->reactor ()->register_handler (this, REGISTER_MASK) == -1)
- {
- ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1);
- }
-
- ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ()));
-
- return 0;
-}
-
-/*
- The destroy() method will remove us from the reactor (with the
- DONT_CALL flag set!) and then free our memory. This allows us to
- be closed from outside of the reactor context without any danger.
- */
-void Client_Handler::destroy (void)
-{
- this->reactor ()->remove_handler (this, REMOVE_MASK );
- delete this;
-}
-
-/*
- As mentioned in the header, the typical way to close an object in a
- threaded context is to invoke it's close() method.
-*/
-int Client_Handler::close(u_long flags)
-{
- /*
- We use the destroy() method to clean up after ourselves.
- That will take care of removing us from the reactor and then
- freeing our memory.
- */
- this->destroy();
-
- /*
- Don't forward the close() to the baseclass! handle_close() above has
- already taken care of delete'ing. Forwarding close() would cause that
- to happen again and things would get really ugly at that point!
- */
- return 0;
-}
-
-/*
- We will be called when handle_input() returns -1. That's our queue
- to delete ourselves to prevent memory leaks.
- */
-int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask)
-{
- ACE_UNUSED_ARG (_handle);
- ACE_UNUSED_ARG (_mask);
-
- delete this;
-
- return 0;
-}
-
-/*
- In the open() method, we registered with the reactor and requested to be
- notified when there is data to be read. When the reactor sees that activity
- it will invoke this handle_input() method on us. As I mentioned, the _handle
- parameter isn't useful to us but it narrows the list of methods the reactor
- has to worry about and the list of possible virtual functions we would have
- to override.
-
- You've read that much before... Now we have to do some extra stuff in case
- we're using the thread-pool implementation. If we're called by our creator
- thread then we must be in the reactor. In that case, we arrange to be put
- into the thread pool. If we're not in the creator thread then we must be
- in the thread pool and we can do some work.
- */
-int Client_Handler::handle_input (ACE_HANDLE _handle)
-{
- ACE_UNUSED_ARG (_handle);
-
- /*
- Check our strategy. If we're using the thread pool and we're in the creation
- thread then we know we were called by the reactor.
- */
- if( concurrency() == Client_Acceptor::thread_pool_ )
- {
- if( ACE_OS::thr_equal(ACE_Thread::self(),creator_) )
- {
- /*
- Remove ourselves from the reactor and ask to be put into the thread pool's
- queue of work. (You should be able to use suspend_handler() but I've had
- problems with that.)
- */
- this->reactor()->remove_handler( this, REMOVE_MASK );
- return this->thread_pool()->enqueue(this);
- }
- }
-
- /*
- Any strategy other than thread-per-connection will eventually get here. If we're in the
- single-threaded implementation or the thread-pool, we still have to pass this way.
- */
-
- char buf[128];
- ACE_OS::memset (buf, 0, sizeof (buf));
-
- /*
- Invoke the process() method to do the work but save it's return value instead
- of returning it immediately.
- */
-
- int rval = this->process(buf,sizeof(buf));
-
- /*
- Now, we look again to see if we're in the thread-pool implementation. If so then we
- need to re-register ourselves with the reactor so that we can get more work when it
- is available. (If suspend_handler() worked then we would use resume_handler() here.)
- */
- if( concurrency() == Client_Acceptor::thread_pool_ )
- {
- if( rval != -1 )
- {
- this->reactor()->register_handler( this, REGISTER_MASK );
- }
- }
-
- /*
- Return the result of process()
- */
- return(rval);
-}
-
-/*
- Remember that when we leave our svc() method, the framework will take care
- of calling our close() method so that we can cleanup after ourselves.
- */
-int Client_Handler::svc(void)
-{
- char buf[128];
- ACE_OS::memset (buf, 0, sizeof (buf));
-
- while( 1 )
- {
- if( this->process(buf,sizeof(buf)) == -1 )
- {
- return(-1);
- }
- }
-
- return(0);
-}
-
-/*
- Once again, we see that the application-level logic has not been at all affected
- by our choice of threading models. Of course, I'm not sharing data between threads
- or anything. We'll leave locking issues for a later tutorial.
- */
-int Client_Handler::process (char *_rdbuf, int _rdbuf_len)
-{
- switch (this->peer ().recv (_rdbuf, _rdbuf_len))
- {
- case -1:
- ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1);
- case 0:
- ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1);
- default:
- ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf));
- }
-
- return 0;
-}
diff --git a/docs/tutorials/007/client_handler.h b/docs/tutorials/007/client_handler.h
deleted file mode 100644
index 6807231c3b0..00000000000
--- a/docs/tutorials/007/client_handler.h
+++ /dev/null
@@ -1,172 +0,0 @@
-
-// $Id$
-
-#ifndef CLIENT_HANDLER_H
-#define CLIENT_HANDLER_H
-
-/*
- Our client handler must exist somewhere in the ACE_Event_Handler object
- hierarchy. This is a requirement of the ACE_Reactor because it maintains
- ACE_Event_Handler pointers for each registered event handler. You could
- derive our Client_Handler directly from ACE_Event_Handler but you still have
- to have an ACE_SOCK_Stream for the actually connection. With a direct
- derivative of ACE_Event_Handler, you'll have to contain and maintain an
- ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a
- derivative of ACE_Event_Handler) some of those details are handled for you.
- */
-
-#include "ace/Svc_Handler.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-#include "ace/SOCK_Stream.h"
-
-class Client_Acceptor;
-class Thread_Pool;
-
-/*
- Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<>
- interface as well. That's what the ACE_NULL_SYNCH parameter below is all
- about. That's beyond our scope here but we'll come back to it in the next
- tutorial when we start looking at concurrency options.
- */
-class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH >
-{
-public:
- typedef ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited;
-
- // Constructor...
- Client_Handler (void);
-
- /*
- The destroy() method is our preferred method of destruction. We could
- have overloaded the delete operator but that is neither easy nor
- intuitive (at least to me). Instead, we provide a new method of
- destruction and we make our destructor protected so that only ourselves,
- our derivatives and our friends can delete us. It's a nice
- compromise.
- */
- void destroy (void);
-
- /*
- Most ACE objects have an open() method. That's how you make them ready
- to do work. ACE_Event_Handler has a virtual open() method which allows us
- to create this overrride. ACE_Acceptor<> will invoke this method after
- creating a new Client_Handler when a client connects. Notice that the
- parameter to open() is a void*. It just so happens that the pointer
- points to the acceptor which created us. You would like for the parameter
- to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that
- would tie it too closely to the ACE_Acceptor<> set of objects. In our
- definition of open() you'll see how we get around that.
- */
- int open (void *_acceptor);
-
- /*
- When an ACE_Task<> object falls out of the svc() method, the framework
- will call the close() method. That's where we want to cleanup ourselves
- if we're running in either thread-per-connection or thread-pool mode.
- */
- int close(u_long flags = 0);
-
- /*
- When there is activity on a registered handler, the handle_input() method
- of the handler will be invoked. If that method returns an error code (eg
- -- -1) then the reactor will invoke handle_close() to allow the object to
- clean itself up. Since an event handler can be registered for more than
- one type of callback, the callback mask is provided to inform
- handle_close() exactly which method failed. That way, you don't have to
- maintain state information between your handle_* method calls. The _handle
- parameter is explained below...
- As a side-effect, the reactor will also invoke remove_handler()
- for the object on the mask that caused the -1 return. This means
- that we don't have to do that ourselves!
- */
- int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask);
-
- /*
- When we register with the reactor, we're going to tell it that we want to
- be notified of READ events. When the reactor sees that there is read
- activity for us, our handle_input() will be invoked. The _handleg
- provided is the handle (file descriptor in Unix) of the actual connection
- causing the activity. Since we're derived from ACE_Svc_Handler<> and it
- maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for
- us. However, if we had been derived directly from ACE_Event_Handler, we
- may have chosen not to contain the peer. In that case, the _handleg
- would be important to us for reading the client's data.
- */
- int handle_input (ACE_HANDLE _handle);
-
-protected:
-
- /*
- If the Client_Acceptor which created us has chosen a thread-per-connection
- strategy then our open() method will activate us into a dedicate thread.
- The svc() method will then execute in that thread performing some of the
- functions we used to leave up to the reactor.
- */
- int svc(void);
-
- /*
- This has nothing at all to do with ACE. I've added this here as a worker
- function which I will call from handle_input(). That allows me to
- introduce concurrencly in later tutorials with a no changes to the worker
- function. You can think of process() as application-level code and
- everything elase as application-framework code.
- */
- int process (char *_rdbuf, int _rdbuf_len);
-
- /*
- We don't really do anything in our destructor but we've declared it to be
- protected to prevent casual deletion of this object. As I said above, I
- really would prefer that everyone goes through the destroy() method to get
- rid of us.
- */
- ~Client_Handler (void);
-
- /*
- When we get to the definition of Client_Handler we'll see that there are
- several places where we go back to the Client_Acceptor for information.
- It is generally a good idea to do that through an accesor rather than
- using the member variable directly.
- */
- Client_Acceptor * client_acceptor( void )
- { return this->client_acceptor_; }
-
- /*
- And since you shouldn't access a member variable directly, neither should you
- set (mutate) it. Although it might seem silly to do it this way, you'll thank
- yourself for it later.
- */
- void client_acceptor( Client_Acceptor * _client_acceptor )
- { this->client_acceptor_ = _client_acceptor; }
-
- /*
- The concurrency() accessor tells us the current concurrency strategy. It actually
- queries the Client_Acceptor for it but by having the accessor in place, we could
- change our implementation without affecting everything that needs to know.
- */
- int concurrency(void);
-
- /*
- Likewise for access to the Thread_Pool that we belong to.
- */
- Thread_Pool * thread_pool(void);
-
-
- Client_Acceptor * client_acceptor_;
-
- /*
- For some reason I didn't create accessor/mutator methods for this. So much for
- consistency....
-
- This variable is used to remember the thread in which we were created: the "creator"
- thread in other words. handle_input() needs to know if it is operating in the
- main reactor thread (which is the one that created us) or if it is operating in
- one of the thread pool threads. More on this when we get to handle_input().
- */
- ACE_thread_t creator_;
-};
-
-#endif // CLIENT_HANDLER_H
diff --git a/docs/tutorials/007/page01.html b/docs/tutorials/007/page01.html
deleted file mode 100644
index 24b94f686c7..00000000000
--- a/docs/tutorials/007/page01.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P>In this tutorial, we're going to extend Tutorial 6 to add a third concurrency
-strategy:&nbsp; thread-pool.&nbsp; Like Tutorial 6 did to Tutorial 5, we're
-going to keep the existing strategies that we've already created and add
-this one in as a "bonus".&nbsp; As you'll see, our basic objects will change
-but not by a whole lot.&nbsp; To accomplish this, we'll introduce one new
-major object that helps to abstract the thread pool concept.
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="..">Tutorial
-Index</A>] [<A HREF="page02.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page02.html b/docs/tutorials/007/page02.html
deleted file mode 100644
index c6e7bedec43..00000000000
--- a/docs/tutorials/007/page02.html
+++ /dev/null
@@ -1,197 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P>As usualy, we start with <A HREF="server.cpp">server.cpp</A>
-<BR>
-<HR WIDTH="100%">
-
-<P><FONT FACE="Arial,Helvetica">// $Id: server.cpp,v 1.1 1998/08/30 16:04:12
-jcej Exp $</FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; We try to keep main() very
-simple.&nbsp; One of the ways we do that is to push</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; much of the complicated stuff
-into worker objects.&nbsp; In this case, we only</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; need to include the acceptor
-header in our main source file.&nbsp; We let it</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; worry about the "real work".</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-
-<P><FONT FACE="Arial,Helvetica">#include "client_acceptor.h"</FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; As before, we create a simple
-signal handler that will set our finished</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; flag.&nbsp; There are, of
-course, more elegant ways to handle program shutdown</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; requests but that isn't really
-our focus right now, so we'll just do the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; easiest thing.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-
-<P><FONT FACE="Arial,Helvetica">static sig_atomic_t finished = 0;</FONT>
-<BR><FONT FACE="Arial,Helvetica">extern "C" void handler (int)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; finished = 1;</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; A server has to listen for
-clients at a known TCP/IP port.&nbsp; The default ACE</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; port is 10002 (at least on
-my system) and that's good enough for what&nbsp; we</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; want to do here.&nbsp; Obviously,
-a more robust application would take a command</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; line parameter or read from
-a configuration file or do some other&nbsp; clever</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; thing.&nbsp; Just like the
-signal handler above, though, that's what we want to</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; focus on, so we're taking
-the easy way out.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-
-<P><FONT FACE="Arial,Helvetica">static const u_short PORT = ACE_DEFAULT_SERVER_PORT;</FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Finally, we get to main.&nbsp;
-Some C++ compilers will complain loudly if your</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; function signature doesn't
-match the prototype.&nbsp; Even though we're not</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; going to use the parameters,
-we still&nbsp; have to specify them.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-
-<P><FONT FACE="Arial,Helvetica">int main (int argc, char *argv[])</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; In our earlier servers, we
-used a global pointer to get to the reactor. I've</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; never really liked that idea,
-so I've moved it into main() this time. When</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; we&nbsp; get to the Client_Handler
-object you'll see how we manage to get a</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; pointer back to this reactor.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; ACE_Reactor reactor;</FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp; /*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; The acceptor
-will take care of letting clients connect to us.&nbsp; It will</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; also arrange
-for a&nbsp; Client_Handler to be created for each new client.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; Since we're only
-going to listen at one&nbsp; TCP/IP port, we only need one</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; acceptor.&nbsp;
-If we wanted, though, we could create several of these&nbsp; and</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; listen at several
-ports.&nbsp; (That's what we would do if we wanted to rewrite</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; inetd for&nbsp;
-instance.)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; */</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; Client_Acceptor peer_acceptor;</FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp; /*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; Create an ACE_INET_Addr
-that represents our endpoint of a connection. We</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; then open our
-acceptor object with that Addr.&nbsp; Doing so tells the acceptor</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; where to listen
-for connections.&nbsp; Servers generally listen at "well known"</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; addresses.&nbsp;
-If not, there must be some mechanism by which the client is</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; informed of the
-server's address.</FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; Note how ACE_ERROR_RETURN
-is used if we fail to open the acceptor.&nbsp; This</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; technique is
-used over and over again in our tutorials.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; */</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; if (peer_acceptor.open (ACE_INET_Addr
-(PORT), &amp;reactor) == -1)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp; ACE_ERROR_RETURN ((LM_ERROR,
-"%p\n", "open"), -1);</FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp; /*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; Install our signal
-handler.&nbsp; You can actually register signal handlers</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; with the reactor.&nbsp;
-You might do that when the signal handler is</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; responsible for
-performing "real" work.&nbsp; Our simple flag-setter doesn't</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; justify deriving
-from ACE_Event_Handler and providing a callback function</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; though.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; */</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; ACE_Sig_Action sa ((ACE_SignalHandler)
-handler, SIGINT);</FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp; /*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; Like ACE_ERROR_RETURN,
-the ACE_DEBUG macro gets used quite a bit.&nbsp; It's a</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; handy way to
-generate uniform debug output from your program.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; */</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; ACE_DEBUG ((LM_DEBUG, "(%P|%t)
-starting up server daemon\n"));</FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp; /*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; This will loop
-"forever" invoking the handle_events() method of our</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; reactor. handle_events()
-watches for activity on any registered handlers</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; and invokes their
-appropriate callbacks when necessary.&nbsp; Callback-driven</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; programming is
-a big thing in ACE, you should get used to it. If the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; signal handler
-catches something, the finished flag will be set and we'll</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; exit.&nbsp; Conveniently
-enough, handle_events() is also interrupted by signals</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; and will exit
-back to the while() loop.&nbsp; (If you want your event loop to</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; not be interrupted
-by signals, checkout the &lt;i>restart&lt;/i> flag on the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; open() method
-of ACE_Reactor if you're interested.)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; */</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; while (!finished)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-reactor.handle_events ();</FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp; ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting
-down server daemon\n"));</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; return 0;</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT>
-
-<P>
-<HR WIDTH="100%">
-
-<P>Hmmm... No change there.&nbsp;&nbsp; Maybe I should leave out comments
-on the stuff I don't change.&nbsp; Let's take a lookt at client_acceptor.h.
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="..">Tutorial
-Index</A>] [<A HREF="page03.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page03.html b/docs/tutorials/007/page03.html
deleted file mode 100644
index af048108811..00000000000
--- a/docs/tutorials/007/page03.html
+++ /dev/null
@@ -1,263 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P>Let's see what things we've had to add to <A HREF="client_acceptor.h">client_acceptor.h</A>.
-
-<P>
-<HR WIDTH="100%">
-<BR><FONT FACE="Arial,Helvetica">// $Id: client_acceptor.h,v 1.1 1998/08/30
-16:04:11 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#ifndef CLIENT_ACCEPTOR_H</FONT>
-<BR><FONT FACE="Arial,Helvetica">#define CLIENT_ACCEPTOR_H</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; The ACE_Acceptor&lt;> template
-lives in the ace/Acceptor.h header file. You'll</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; find a very consitent naming
-convention between the ACE objects and the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; headers where they can be
-found.&nbsp; In general, the ACE object ACE_Foobar will</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; be found in ace/Foobar.h.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#include "ace/Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Since we want to work with
-sockets, we'll need a SOCK_Acceptor to allow the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; clients to connect to us.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">#include "ace/SOCK_Acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; The Client_Handler object
-we develop will be used to handle clients once</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; they're connected.&nbsp;
-The ACE_Acceptor&lt;> template's first parameter requires</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; such an object.&nbsp; In
-some cases, you can get by with just a forward</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; declaration on the class,
-in others you have to have the whole thing.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">#include "client_handler.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Parameterize the ACE_Acceptor&lt;>
-such that it will listen for socket</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; connection attempts and create
-Client_Handler objects when they happen. In</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Tutorial 001, we wrote the
-basic acceptor logic on our own before we</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; realized that ACE_Acceptor&lt;>
-was available.&nbsp; You'll get spoiled using the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; ACE templates because they
-take away a lot of the tedious details!</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">typedef ACE_Acceptor &lt; Client_Handler,
-ACE_SOCK_ACCEPTOR > Client_Acceptor_Base;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#include "thread_pool.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; This time we've added quite
-a bit more to our acceptor.&nbsp; In addition to</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; providing a choice of concurrency
-strategies, we also maintain a Thread_Pool</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; object in case that strategy
-is chosen.&nbsp; The object still isn't very complex</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; but it's come a long way
-from the simple typedef we had in Tutorial 5.</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Why keep the thread pool as
-a member?&nbsp; If we go back to the inetd concept</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; you'll recall that we need
-several acceptors to make that work.&nbsp; We may have</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; a situation in which our
-different client types requre different resources.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; That is, we may need a large
-thread pool for some client types and a smaller</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; one for others.&nbsp; We
-could share a pool but then the client types may have</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; undesirable impact on one
-another.</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Just in case you do want to
-share a single thread pool, there is a constructor</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; below that will let you do
-that.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">class Client_Acceptor : public Client_Acceptor_Base</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">public:</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-typedef Client_Acceptor_Base inherited;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Now that we have more than two strategies, we need more than a boolean</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-to tell us what we're using.&nbsp; A set of enums is a good choice because</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-it allows us to use named values.&nbsp; Another option would be a set of</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-static const integers.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-enum concurrency_t</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-single_threaded_,</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-thread_per_connection_,</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-thread_pool_</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-};</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-The default constructor allows the programmer to choose the concurrency</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-strategy.&nbsp; Since we want to focus on thread-pool, that's what we'll
-use</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if nothing is specified.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Client_Acceptor( int _concurrency = thread_pool_ );</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Another option is to construct the object with an existing thread pool.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-The&nbsp; concurrency strategy is pretty obvious at that point.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Client_Acceptor( Thread_Pool &amp; _thread_pool );</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Our destructor will take care of shutting down the thread-pool</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if applicable.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-~Client_Acceptor( void );</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Open ourselves and register with the given reactor.&nbsp; The thread pool
-size</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-can be specified here if you want to use that concurrency strategy.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int open( const ACE_INET_Addr &amp; _addr, ACE_Reactor * _reactor,</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int _pool_size = Thread_Pool::default_pool_size_ );</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Close ourselves and our thread pool if applicable</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int close(void);</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-What is our concurrency strategy?</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int concurrency(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{ return this->concurrency_; }</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Give back a pointer to our thread pool.&nbsp; Our Client_Handler objects</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-will need this so that their handle_input() methods can put themselves</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-into the pool.&nbsp; Another alternative would be a globally accessible</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-thread pool.&nbsp; ACE_Singleton&lt;> is a way to achieve that.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Thread_Pool * thread_pool(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{ return &amp; this->the_thread_pool_; }</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Since we can be constructed with a Thread_Pool reference, there are times</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-when we need to know if the thread pool we're using is ours or if we're</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-just borrowing it from somebody else.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int thread_pool_is_private(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{ return &amp;the_thread_pool_ == &amp;private_thread_pool_; }</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">protected:</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int concurrency_;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Thread_Pool&nbsp;&nbsp; private_thread_pool_;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Thread_Pool &amp; the_thread_pool_;</FONT>
-<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#endif // CLIENT_ACCEPTOR_H</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P>
-<HR WIDTH="100%">
-
-<P>Well, except for the new Thread_Pool member variable, most of the changes
-are informational.
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page04.html b/docs/tutorials/007/page04.html
deleted file mode 100644
index 34424605180..00000000000
--- a/docs/tutorials/007/page04.html
+++ /dev/null
@@ -1,133 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P>Something new this time is <A HREF="client_acceptor.cpp">client_acceptor.cpp</A>.&nbsp;
-I finally had enough code to move it out of the header.
-
-<P>
-<HR WIDTH="100%">
-<BR><FONT FACE="Arial,Helvetica">// $Id: client_acceptor.cpp,v 1.1 1998/08/30
-16:04:11 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#include "client_acceptor.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Construct ourselves with
-the chosen concurrency strategy.&nbsp; Notice that we also</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; set our Thread_Pool reference
-to our private instance.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">Client_Acceptor::Client_Acceptor( int
-_concurrency )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;:&nbsp; concurrency_(_concurrency)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; ,the_thread_pool_(private_thread_pool_)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Construct ourselves with
-a reference to somebody else' Thread_Pool.&nbsp; Obvioulsy</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; our concurrency strategy
-is "thread_pool_" at this point.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">Client_Acceptor::Client_Acceptor( Thread_Pool
-&amp; _thread_pool )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;:&nbsp; concurrency_(thread_pool_)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; ,the_thread_pool_(_thread_pool)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; When we're destructed, we
-may need to cleanup after ourselves.&nbsp; If we're running</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; with a thread pool that we
-own, it is up to us to close it down.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">Client_Acceptor::~Client_Acceptor( void
-)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if( this->concurrency() == thread_pool_ &amp;&amp; thread_pool_is_private()
-)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-thread_pool()->close();</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Similar to the destructor
-(and close() below) it is necessary for us to open the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; thread pool in some circumstances.</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Notice how we delegate most
-of the open() work to the open() method of our baseclass.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">int Client_Acceptor::open( const ACE_INET_Addr
-&amp; _addr, ACE_Reactor * _reactor, int _pool_size )</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if( this->concurrency() == thread_pool_ &amp;&amp; thread_pool_is_private()
-)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-thread_pool()->open(_pool_size);</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return inherited::open(_addr,_reactor);</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Here again we find that we
-have to manage the thread pool.&nbsp; Like open() we also delegate</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; the other work to our baseclass.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">int Client_Acceptor::close(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if( this->concurrency() == thread_pool_ &amp;&amp; thread_pool_is_private()
-)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-thread_pool()->close();</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return inherited::close();</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT>
-<BR><FONT FACE="Arial,Helvetica"></FONT>&nbsp;<FONT FACE="Arial,Helvetica"></FONT>
-
-<P>
-<HR WIDTH="100%">
-
-<P>Nothing really surprising here.&nbsp; Most of it just manages the Thread_Pool.
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page05.html b/docs/tutorials/007/page05.html
deleted file mode 100644
index c797b188cec..00000000000
--- a/docs/tutorials/007/page05.html
+++ /dev/null
@@ -1,208 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P>As you might expect, <A HREF="client_handler.h">client_handler.h</A>
-is next.
-
-<P>
-<HR WIDTH="100%">
-<pre><FONT FACE="Arial,Helvetica">
-#ifndef CLIENT_HANDLER_H
-#define CLIENT_HANDLER_H
-
-/*
- Our client handler must exist somewhere in the ACE_Event_Handler object
- hierarchy. This is a requirement of the ACE_Reactor because it maintains
- ACE_Event_Handler pointers for each registered event handler. You could
- derive our Client_Handler directly from ACE_Event_Handler but you still have
- to have an ACE_SOCK_Stream for the actually connection. With a direct
- derivative of ACE_Event_Handler, you'll have to contain and maintain an
- ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a
- derivative of ACE_Event_Handler) some of those details are handled for you.
- */
-
-#include "ace/Svc_Handler.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-#include "ace/SOCK_Stream.h"
-
-class Client_Acceptor;
-class Thread_Pool;
-
-/*
- Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task<>
- interface as well. That's what the ACE_NULL_SYNCH parameter below is all
- about. That's beyond our scope here but we'll come back to it in the next
- tutorial when we start looking at concurrency options.
- */
-class Client_Handler : public ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH >
-{
-public:
- typedef ACE_Svc_Handler < ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited;
-
- // Constructor...
- Client_Handler (void);
-
- /*
- The destroy() method is our preferred method of destruction. We could
- have overloaded the delete operator but that is neither easy nor
- intuitive (at least to me). Instead, we provide a new method of
- destruction and we make our destructor protected so that only ourselves,
- our derivatives and our friends can delete us. It's a nice
- compromise.
- */
- void destroy (void);
-
- /*
- Most ACE objects have an open() method. That's how you make them ready
- to do work. ACE_Event_Handler has a virtual open() method which allows us
- to create this overrride. ACE_Acceptor<> will invoke this method after
- creating a new Client_Handler when a client connects. Notice that the
- parameter to open() is a void*. It just so happens that the pointer
- points to the acceptor which created us. You would like for the parameter
- to be an ACE_Acceptor<>* but since ACE_Event_Handler is generic, that
- would tie it too closely to the ACE_Acceptor<> set of objects. In our
- definition of open() you'll see how we get around that.
- */
- int open (void *_acceptor);
-
- /*
- When an ACE_Task<> object falls out of the svc() method, the framework
- will call the close() method. That's where we want to cleanup ourselves
- if we're running in either thread-per-connection or thread-pool mode.
- */
- int close(u_long flags = 0);
-
- /*
- When there is activity on a registered handler, the handle_input() method
- of the handler will be invoked. If that method returns an error code (eg
- -- -1) then the reactor will invoke handle_close() to allow the object to
- clean itself up. Since an event handler can be registered for more than
- one type of callback, the callback mask is provided to inform
- handle_close() exactly which method failed. That way, you don't have to
- maintain state information between your handle_* method calls. The _handle
- parameter is explained below...
- As a side-effect, the reactor will also invoke remove_handler()
- for the object on the mask that caused the -1 return. This means
- that we don't have to do that ourselves!
- */
- int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask);
-
- /*
- When we register with the reactor, we're going to tell it that we want to
- be notified of READ events. When the reactor sees that there is read
- activity for us, our handle_input() will be invoked. The _handleg
- provided is the handle (file descriptor in Unix) of the actual connection
- causing the activity. Since we're derived from ACE_Svc_Handler<> and it
- maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for
- us. However, if we had been derived directly from ACE_Event_Handler, we
- may have chosen not to contain the peer. In that case, the _handleg
- would be important to us for reading the client's data.
- */
- int handle_input (ACE_HANDLE _handle);
-
-protected:
-
- /*
- If the Client_Acceptor which created us has chosen a thread-per-connection
- strategy then our open() method will activate us into a dedicate thread.
- The svc() method will then execute in that thread performing some of the
- functions we used to leave up to the reactor.
- */
- int svc(void);
-
- /*
- This has nothing at all to do with ACE. I've added this here as a worker
- function which I will call from handle_input(). That allows me to
- introduce concurrencly in later tutorials with a no changes to the worker
- function. You can think of process() as application-level code and
- everything elase as application-framework code.
- */
- int process (char *_rdbuf, int _rdbuf_len);
-
- /*
- We don't really do anything in our destructor but we've declared it to be
- protected to prevent casual deletion of this object. As I said above, I
- really would prefer that everyone goes through the destroy() method to get
- rid of us.
- */
- ~Client_Handler (void);
-
- /*
- When we get to the definition of Client_Handler we'll see that there are
- several places where we go back to the Client_Acceptor for information.
- It is generally a good idea to do that through an accesor rather than
- using the member variable directly.
- */
- Client_Acceptor * client_acceptor( void )
- { return this->client_acceptor_; }
-
- /*
- And since you shouldn't access a member variable directly, neither should you
- set (mutate) it. Although it might seem silly to do it this way, you'll thank
- yourself for it later.
- */
- void client_acceptor( Client_Acceptor * _client_acceptor )
- { this->client_acceptor_ = _client_acceptor; }
-
- /*
- The concurrency() accessor tells us the current concurrency strategy. It actually
- queries the Client_Acceptor for it but by having the accessor in place, we could
- change our implementation without affecting everything that needs to know.
- */
- int concurrency(void);
-
- /*
- Likewise for access to the Thread_Pool that we belong to.
- */
- Thread_Pool * thread_pool(void);
-
-
- Client_Acceptor * client_acceptor_;
-
- /*
- For some reason I didn't create accessor/mutator methods for this. So much for
- consistency....
-
- This variable is used to remember the thread in which we were created: the "creator"
- thread in other words. handle_input() needs to know if it is operating in the
- main reactor thread (which is the one that created us) or if it is operating in
- one of the thread pool threads. More on this when we get to handle_input().
- */
- ACE_thread_t creator_;
-};
-
-#endif // CLIENT_HANDLER_H
-</pre>
-<HR WIDTH="100%">
-
-<P>Still, we're just not seeing a lot of changes due to intruduction of
-the thread pool.&nbsp; That's a good thing! You don't want to go turning
-your application upside down just because you changed thread models.
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="..">Tutorial
-Index</A>] [<A HREF="page06.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page06.html b/docs/tutorials/007/page06.html
deleted file mode 100644
index 3c2fdd30357..00000000000
--- a/docs/tutorials/007/page06.html
+++ /dev/null
@@ -1,272 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P><A HREF="client_handler.cpp">client_handler.cpp</A>
-shows some of the changes due to the thread-pool.&nbsp;&nbsp; Just a few
-though.
-
-<P>
-<HR WIDTH="100%">
-<pre><FONT FACE="Arial,Helvetica">
-/*
- Since this is the third time we've seen most of this, I'm going to strip out almost
- all of the comments that you've already seen. That way, you can concentrate on the
- new items.
- */
-
-#include "client_acceptor.h"
-#include "client_handler.h"
-
-/*
- We're going to be registering and unregistering a couple of times. To make sure that
- we use the same flags every time, I've created these handy macros.
- */
-#define REGISTER_MASK ACE_Event_Handler::READ_MASK
-#define REMOVE_MASK (ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL)
-
-/*
- Our constructor still doesn't really do anything. We simply initialize the acceptor
- pointer to "null" and get our current thread id. The static self() method of ACE_Thread
- will return you a thread id native to your platform.
- */
-Client_Handler::Client_Handler (void)
- : client_acceptor_(0)
- ,creator_(ACE_Thread::self())
-{
-}
-
-Client_Handler::~Client_Handler (void)
-{
- this->peer().close();
-}
-
-/*
- Query our acceptor for the concurrency strategy. Notice that we don't bother
- to check that our acceptor pointer is valid. That is proably a bad idea...
- */
-int Client_Handler::concurrency(void)
-{
- return this->client_acceptor()->concurrency();
-}
-
-/*
- And here we ask the acceptor about the thread pool.
- */
-Thread_Pool * Client_Handler::thread_pool(void)
-{
- return this->client_acceptor()->thread_pool();
-}
-
-/*
- Back to our open() method. This is straight out of Tutorial 6. There's
- nothing additional here for the thread-pool implementation.
- */
-int Client_Handler::open (void *_acceptor)
-{
- client_acceptor( (Client_Acceptor *) _acceptor );
-
- if( concurrency() == Client_Acceptor::thread_per_connection_ )
- {
- return this->activate();
- }
-
- this->reactor (client_acceptor()->reactor ());
-
- ACE_INET_Addr addr;
-
- if (this->peer ().get_remote_addr (addr) == -1)
- {
- return -1;
- }
-
- if (this->reactor ()->register_handler (this, REGISTER_MASK) == -1)
- {
- ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1);
- }
-
- ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected with %s\n", addr.get_host_name ()));
-
- return 0;
-}
-
-/*
- The destroy() method will remove us from the reactor (with the
- DONT_CALL flag set!) and then free our memory. This allows us to
- be closed from outside of the reactor context without any danger.
- */
-void Client_Handler::destroy (void)
-{
- this->reactor ()->remove_handler (this, REMOVE_MASK );
- delete this;
-}
-
-/*
- As mentioned in the header, the typical way to close an object in a
- threaded context is to invoke it's close() method. We use the
- destroy() method to clean up after ourselves.
-*/
-int Client_Handler::close(u_long flags)
-{
- this->destroy();
-
- /*
- Don't forward the close() to the baseclass! handle_close() above has
- already taken care of delete'ing. Forwarding close() would cause that
- to happen again and things would get really ugly at that point!
- */
- return 0;
-}
-
-/*
- We will be called when handle_input() returns -1. That's our queue
- to delete ourselves to prevent memory leaks.
- */
-int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask)
-{
- ACE_UNUSED_ARG (_handle);
- ACE_UNUSED_ARG (_mask);
-
- delete this;
-
- return 0;
-}
-
-/*
- In the open() method, we registered with the reactor and requested to be
- notified when there is data to be read. When the reactor sees that activity
- it will invoke this handle_input() method on us. As I mentioned, the _handle
- parameter isn't useful to us but it narrows the list of methods the reactor
- has to worry about and the list of possible virtual functions we would have
- to override.
-
- You've read that much before... Now we have to do some extra stuff in case
- we're using the thread-pool implementation. If we're called by our creator
- thread then we must be in the reactor. In that case, we arrange to be put
- into the thread pool. If we're not in the creator thread then we must be
- in the thread pool and we can do some work.
- */
-int Client_Handler::handle_input (ACE_HANDLE _handle)
-{
- ACE_UNUSED_ARG (_handle);
-
- /*
- Check our strategy. If we're using the thread pool and we're in the creation
- thread then we know we were called by the reactor.
- */
- if( concurrency() == Client_Acceptor::thread_pool_ )
- {
- if( ACE_OS::thr_equal(ACE_Thread::self(),creator_) )
- {
- /*
- Remove ourselves from the reactor and ask to be put into the thread pool's
- queue of work. (You should be able to use suspend_handler() but I've had
- problems with that.)
- */
- this->reactor()->remove_handler( this, REMOVE_MASK );
- return this->thread_pool()->enqueue(this);
- }
- }
-
- /*
- Any strategy other than thread-per-connection will eventually get here. If we're in the
- single-threaded implementation or the thread-pool, we still have to pass this way.
- */
-
- char buf[128];
- ACE_OS::memset (buf, 0, sizeof (buf));
-
- /*
- Invoke the process() method to do the work but save it's return value instead
- of returning it immediately.
- */
-
- int rval = this->process(buf,sizeof(buf));
-
- /*
- Now, we look again to see if we're in the thread-pool implementation. If so then we
- need to re-register ourselves with the reactor so that we can get more work when it
- is available. (If suspend_handler() worked then we would use resume_handler() here.)
- */
- if( concurrency() == Client_Acceptor::thread_pool_ )
- {
- if( rval != -1 )
- {
- this->reactor()->register_handler( this, REGISTER_MASK );
- }
- }
-
- /*
- Return the result of process()
- */
- return(rval);
-}
-
-/*
- Remember that when we leave our svc() method, the framework will take care
- of calling our close() method so that we can cleanup after ourselves.
- */
-int Client_Handler::svc(void)
-{
- char buf[128];
- ACE_OS::memset (buf, 0, sizeof (buf));
-
- while( 1 )
- {
- if( this->process(buf,sizeof(buf)) == -1 )
- {
- return(-1);
- }
- }
-
- return(0);
-}
-
-/*
- Once again, we see that the application-level logic has not been at all affected
- by our choice of threading models. Of course, I'm not sharing data between threads
- or anything. We'll leave locking issues for a later tutorial.
- */
-int Client_Handler::process (char *_rdbuf, int _rdbuf_len)
-{
- switch (this->peer ().recv (_rdbuf, _rdbuf_len))
- {
- case -1:
- ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1);
- case 0:
- ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), -1);
- default:
- ACE_DEBUG ((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf));
- }
-
- return 0;
-}
-</pre>
-<HR WIDTH="100%">
-
-<P>Ok, now we've gone and changed handle_input() so that it knows when
-to do work and when to enqueue itself.&nbsp; Beyond that, we're still about
-the same.
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="..">Tutorial
-Index</A>] [<A HREF="page07.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page07.html b/docs/tutorials/007/page07.html
deleted file mode 100644
index c4fd555cf68..00000000000
--- a/docs/tutorials/007/page07.html
+++ /dev/null
@@ -1,197 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P>Two new files this time.&nbsp; The first is <A HREF="thread_pool.h">thread_pool.h</A>
-where we declare our Thread_Pool object.&nbsp; This is responsible for
-abstracting away the thread pool implementation details and allowing us
-to make so few changes to the rest of the code.
-
-<P>
-<HR WIDTH="100%"><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">// $Id: thread_pool.h,v 1.1 1998/08/30
-16:04:12 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#ifndef THREAD_POOL_H</FONT>
-<BR><FONT FACE="Arial,Helvetica">#define THREAD_POOL_H</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; In order to implement a thread
-pool, we have to have an object that can create</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; a thread.&nbsp; The ACE_Task&lt;>
-is the basis for doing just such a thing.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">#include "ace/Task.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; We need a forward reference
-for ACE_Event_Handler so that our enqueue() method</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; can accept a pointer to one.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">class ACE_Event_Handler;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Although we modified the
-rest of our program to make use of the thread pool</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; implementation, if you look
-closely you'll see that the changes were rather</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; minor.&nbsp; The "ACE way"
-is generally to create a helper object that abstracts</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; away the details not relevant
-to your application.&nbsp; That's what I'm trying</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; to do here by creating the
-Thread_Pool object.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">class Thread_Pool : public ACE_Task&lt;ACE_MT_SYNCH></FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">public:</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Provide an enumeration for the default pool size.&nbsp; By doing this,
-other objects</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-can use the value when they want a default.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-enum size_t</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-default_pool_size_ = 5</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-};</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-// Basic constructor</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Thread_Pool(void);</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Opening the thread pool causes one or more threads to be activated.&nbsp;
-When activated,</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-they all execute the svc() method declared below.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int open( int _pool_size = default_pool_size_ );</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-When you're done wit the thread pool, you have to have some way to shut
-it down.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-This is what close() is for.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int close(void);</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-To use the thread pool, you have to put some unit of work into it.&nbsp;
-Since we're</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-dealing with event handlers (or at least their derivatives), I've chosen
-to provide</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-an enqueue() method that takes a pointer to an ACE_Event_Handler.&nbsp;
-The handler's</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-handle_input() method will be called, so your object has to know when it
-is being</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-called by the thread pool.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int enqueue( ACE_Event_Handler * _handler );</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">protected:</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Our svc() method will dequeue the enqueued event handler objects and invoke
-the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-handle_input() method on each.&nbsp; Since we're likely running in more
-than one thread,</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-idle threads can take work from the queue while other threads are busy
-executing</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-handle_input() on some object.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int svc(void);</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Another handy ACE template is ACE_Atomic_Op&lt;>.&nbsp; When parameterized,
-this allows</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-is to have a thread-safe counting object.&nbsp; The typical arithmetic
-operators are</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-all internally thread-safe so that you can share it across threads without
-worrying</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-about any contention issues.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-typedef ACE_Atomic_Op&lt;ACE_Mutex,int> counter_t;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-We use the atomic op to keep a count of the number of threads in which
-our svc()</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-method is running.&nbsp; This is particularly important when we want to
-close() it down!</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-counter_t active_threads_;</FONT>
-<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#endif // THREAD_POOL_H</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P>
-<HR WIDTH="100%">
-
-<P>Well, that doesn't look too complex.&nbsp; What about the implementation?
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page08.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page08.html b/docs/tutorials/007/page08.html
deleted file mode 100644
index 094804e743d..00000000000
--- a/docs/tutorials/007/page08.html
+++ /dev/null
@@ -1,537 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 007</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
-
-<P>Finally, <A HREF="thread_pool.cpp">thread_pool.cpp</A>
-where we have the Thread_Pool object implementation.
-
-<P>
-<HR WIDTH="100%">
-
-<P><FONT FACE="Arial,Helvetica">// $Id: thread_pool.cpp,v 1.1 1998/08/30
-23:47:15 schmidt Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">#include "thread_pool.h"</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; We need this header so that
-we can invoke handle_input() on the objects we dequeue.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">#include "ace/Event_Handler.h"</FONT>
-<BR><FONT FACE="Arial,Helvetica"></FONT>&nbsp;<FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; All we do here is initialize
-our active thread counter.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">Thread_Pool::Thread_Pool(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;: active_threads_(0)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Our open() method is a thin
-disguise around the ACE_Task&lt;> activate() method.&nbsp; By</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; hiding activate() in this
-way, the users of Thread_Pool don't have to worry about</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; the thread configuration
-flags.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::open( int _pool_size
-)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp; return this->activate(THR_NEW_LWP|THR_DETACHED,_pool_size);</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Closing the thread pool can
-be a tricky exercise.&nbsp; I've decided to take an easy approach</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; and simply enqueue a secret
-message for each thread we have active.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::close(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Find out how many threads are currently active</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-int counter = active_threads_.value();</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-For each one of the active threads, enqueue a "null" event handler.&nbsp;
-Below, we'll</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-teach our svc() method that "null" means "shutdown".</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-while( counter-- )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-this->enqueue( 0 );</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-As each svc() method exits, it will decrement the active thread counter.&nbsp;
-We just wait</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-here for it to reach zero.&nbsp; Since we don't know how long it will take,
-we sleep for</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-a quarter-second or so between tries.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-while( active_threads_.value() )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_OS::sleep( ACE_Time_Value(0.25) );</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return(0);</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; When an object wants to do
-work in the pool, it should call the enqueue() method.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; We introduce the ACE_Message_Block
-here but, unfortunately, we seriously missuse it.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::enqueue( ACE_Event_Handler
-* _handler )</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-An ACE_Message_Block is a chunk of data.&nbsp; You put them into an ACE_Message_Queue.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_Task&lt;> has an ACE_Message_Queue built in.&nbsp; In fact, the parameter
-to ACE_Task&lt;></FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-is passed directly to ACE_Message_Queue.&nbsp; If you look back at our
-header file you'll</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-see that we used ACE_MT_SYNCH as the parameter indicating that we want
-MultiThread</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Synch safety.&nbsp; This allows us to safely put ACE_Message_Block objects
-into the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-message queue in one thread and take them out in another.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-An ACE_Message_Block wants to have char* data.&nbsp; We don't have that.&nbsp;
-We could</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-cast our ACE_Event_Handler* directly to a char* but I wanted to be more
-explicit.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Since casting pointers around is a dangerous thing, I've gone out of my
-way here</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-to be very clear about what we're doing.</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-First:&nbsp; Cast the handler pointer to a void pointer.&nbsp; You can't
-do any useful work</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-on a void pointer, so this is a clear message that we're making the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-pointer unusable.</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Next:&nbsp;&nbsp; Cast the void pointer to a char pointer that the ACE_Message_Block
-will accept.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-void * v_data = (void*)_handler;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-char * c_data = (char*)v_data;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Construct a new ACE_Message_Block.&nbsp; For efficiency, you might want
-to preallocate a</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-stack of these and reuse them.&nbsp; For simplicity, I'll just create what
-I need as I need it.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_Message_Block * mb = new ACE_Message_Block( c_data );</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Our putq() method is a wrapper around one of the enqueue methods of the
-ACE_Message_Queue</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-that we own.&nbsp; Like all good methods, it returns -1 if it fails for
-some reason.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if( this->putq(mb) == -1 )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Another trait of the ACE_Message_Block objects is that they are reference
-counted.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Since they're designed to be passed around between various objects in several
-threads</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-we can't just delete them whenever we feel like it.&nbsp; The release()
-method is similar</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-to the destroy() method we've used elsewhere.&nbsp; It watches the reference
-count and will</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-delete the object when possible.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-mb->release();</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return(-1);</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return(0);</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; The "guard" concept is very
-powerful and used throughout multi-threaded applications.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; A guard normally does some
-operation on an object at construction and the "opposite"</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; operation at destruction.&nbsp;
-For instance, when you guard a mutex (lock) object, the guard</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; will acquire the lock on
-construction and release it on destruction.&nbsp; In this way, your</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; method can simply let the
-guard go out of scope and know that the lock is released.</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Guards aren't only useful
-for locks however.&nbsp; In this application I've created two guard</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; objects for quite a different
-purpose.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; The Counter_Guard is constructed
-with a reference to the thread pool's active thread</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; counter.&nbsp; The guard
-increments the counter when it is created and decrements it at</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; destruction.&nbsp; By creating
-one of these in svc(), I know that the counter will be decremented</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; no matter how or where svc()
-returns.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">class Counter_Guard</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">public:</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Counter_Guard( Thread_Pool::counter_t &amp; _counter )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-: counter_(_counter)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-++counter_;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-~Counter_Guard(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
---counter_;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">protected:</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Thread_Pool::counter_t &amp; counter_;</FONT>
-<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; My Message_Block_Guard is
-also a little non-traditional.&nbsp; It doesn't do anything in the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; constructor but it's destructor
-ensures that the message block's release() method is called.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; This is a cheap way to prevent
-a memory leak if I need an additional exit point in svc().</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">class Message_Block_Guard</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">public:</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Message_Block_Guard( ACE_Message_Block * &amp; _mb )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-: mb_(_mb)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-~Message_Block_Guard( void )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-mb_->release();</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">protected:</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_Message_Block * &amp; mb_;</FONT>
-<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Now we come to the svc()
-method.&nbsp; As I said, this is being executed in each thread of the</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Thread_Pool.&nbsp; Here,
-we pull messages off of our built-in ACE_Message_Queue and cause them</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; to do work.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">int Thread_Pool::svc(void)</FONT>
-<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-The getq() method takes a reference to a pointer.&nbsp; So... we need a
-pointer to give it</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-a reference to.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_Message_Block * mb;</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Create the guard for our active thread counter object.&nbsp; No matter
-where we choose to</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return() from svc(), we no know that the counter will be decremented.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Counter_Guard counter_guard(active_threads_);</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Get messages from the queue until we have a failure.&nbsp; There's no real
-good reason</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-for failure so if it happens, we leave immediately.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-while( this->getq(mb) != -1 )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-A successful getq() will cause "mb" to point to a valid refernce-counted</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_Message_Block.&nbsp; We use our guard object here so that we're sure
-to call</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-the release() method of that message block and reduce it's reference count.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Once the count reaches zero, it will be deleted.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Message_Block_Guard message_block_guard(mb);</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-As noted before, the ACE_Message_Block stores it's data as a char*.&nbsp;
-We pull that</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-out here and later turn it into an ACE_Event_Handler*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-char * c_data = mb->base();</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-We've chosen to use a "null" value as an indication to leave.&nbsp; If
-the data we got</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-from the queue is not null then we have some work to do.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if( c_data )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Once again, we go to great lengths to emphasize the fact that we're casting
-pointers</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-around in rather impolite ways.&nbsp; We could have cast the char* directly
-to an</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_Event_Handler* but then folks might think that's an OK thing to do.</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-(Note:&nbsp; The correct way to use an ACE_Message_Block is to write data
-into it.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-What I should have done was create a message block big enough to hold an</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-event handler pointer and then written the pointer value into the block.&nbsp;
-When</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-we got here, I would have to read that data back into a pointer.&nbsp;
-While politically</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-correct, it is also a lot of work.&nbsp; If you're careful you can get
-away with casting</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-pointers around.)</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-void * v_data = (void*)c_data;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-ACE_Event_Handler * handler = (ACE_Event_Handler*)v_data;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Now that we finally have an event handler pointer, invoke it's handle_input()
-method.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Since we don't know it's handle, we just give it a default.&nbsp; That's
-OK because we</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-know that we're not using the handle in the method anyway.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-if( handler->handle_input(ACE_INVALID_HANDLE) == -1 )</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Tell the handler that it's time to go home.&nbsp; The "normal" method for
-shutting</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-down a handler whose handler failed is to invoke handle_close().&nbsp;
-This will</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-take care of cleaning it up for us.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Notice how we use the handler's get_handle() method to populate it's "handle"</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-parameter.&nbsp; Convenient isn't it?</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-handler->handle_close(handler->get_handle(),0);</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-Also notice that we don't exit the svc() method here!&nbsp; The first time
-I did</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-this, I was exiting.&nbsp; After a few clients disconnect you have an empty</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-thread pool.&nbsp; Hard to do any more work after that...</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-else</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-{</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-/*</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-If we get here, we were given a message block with "null" data.&nbsp; That
-is our</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-signal to leave, so we return(0) to leave gracefully.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-*/</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-// Ok, shutdown request</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-// message_block_guard goes out of scope here</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-// and releases the message_block instance.</FONT>
-<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
-return(0);</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT>
-
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="..">Tutorial
-Index</A>] [<A HREF="page09.html">Continue
-This Tutorial</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/page09.html b/docs/tutorials/007/page09.html
deleted file mode 100644
index 00e9ff650b5..00000000000
--- a/docs/tutorials/007/page09.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<HTML>
-<HEAD>
- <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
- <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]">
- <META NAME="Author" CONTENT="James CE Johnson">
- <META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 006</TITLE>
-</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER>
-
-<HR WIDTH="100%">
-
-<P>That's it for Tutorial 7.&nbsp; As with Tutorial 6, we really didn't
-have to change much to introduce a new threading strategy.&nbsp; Most of
-the work was in creating the Thread_Pool object itself.&nbsp; Everything
-else was just minor housekeeping.
-
-<P>There is a fourth common thread strategy:&nbsp; thread-per-request.&nbsp;
-It's not one of my favorites, so I wasn't planning to go into it.&nbsp;
-If you want to contribute a tutorial on that topic though, I'll be glad
-to include it here.
-
-<P>For reference, here's the file list again:
-<UL>
-<LI>
-<A HREF="Makefile">Makefile</A></LI>
-
-<LI>
-<A HREF="client_acceptor.h">client_acceptor.h</A></LI>
-
-<LI>
-<A HREF="client_acceptor.cpp">client_acceptor.cpp</A></LI>
-
-<LI>
-<A HREF="client_handler.cpp">client_handler.cpp</A></LI>
-
-<LI>
-<A HREF="client_handler.h">client_handler.h</A></LI>
-
-<LI>
-<A HREF="server.cpp">server.cpp</A></LI>
-
-<LI>
-<A HREF="thread_pool.h">thread_pool.h</A></LI>
-
-<LI>
-<A HREF="thread_pool.cpp">thread_pool.cpp</A></LI>
-
-<LI>
-<A HREF="fix.Makefile">fix.Makefile</A></LI>
-</UL>
-<P>
-<HR WIDTH="100%">
-<P>
-<center><h2>Danger, Warning!</h2></center>
-Now that I've gone through all of this to create a thread pool server,
-I have to point out that this isn't exactly the best or safest way to
-do so. The biggest danger we face with this approach is the
-possibility of an event handler existing in the thread pool's message
-queue <i>after</i> it has been deleted. When the thread's svc()
-method attempts to invoke <i>handle_input()</i> you will get a nasty
-core dump.
-<p>
-The safest way to handle the situation is to use reference-counted
-pointers everywhere a Client_Handler pointer would be used. That's
-beyond the scope of the tutorial but I encourage you to give it a
-try. If you want to contribute that back as an enhanced Tutorial,
-I'll be glad to include it.
-<p>
-Another approach that should work quite well is to use the
-ACE_TP_Reactor instead of just ACE_Reactor. This takes a little more
-setup but results in a cleaner implementation. Again, I've not had
-time to develop a Tutorial on the TP_Reactor but would welcome any
-contributions.
-<P>
-<HR WIDTH="100%">
-<CENTER>[<A HREF="..">Tutorial
-Index</A>]</CENTER>
-
-</BODY>
-</HTML>
diff --git a/docs/tutorials/007/server.cpp b/docs/tutorials/007/server.cpp
deleted file mode 100644
index 55fb69c58ef..00000000000
--- a/docs/tutorials/007/server.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-// $Id$
-
-/*
- We try to keep main() very simple. One of the ways we do that is to push
- much of the complicated stuff into worker objects. In this case, we only
- need to include the acceptor header in our main source file. We let it
- worry about the "real work".
- */
-
-#include "client_acceptor.h"
-
-/*
- As before, we create a simple signal handler that will set our finished
- flag. There are, of course, more elegant ways to handle program shutdown
- requests but that isn't really our focus right now, so we'll just do the
- easiest thing.
- */
-
-static sig_atomic_t finished = 0;
-extern "C" void handler (int)
-{
- finished = 1;
-}
-
-/*
- A server has to listen for clients at a known TCP/IP port. The default ACE
- port is 10002 (at least on my system) and that's good enough for what we
- want to do here. Obviously, a more robust application would take a command
- line parameter or read from a configuration file or do some other clever
- thing. Just like the signal handler above, though, that's what we want to
- focus on, so we're taking the easy way out.
- */
-
-static const u_short PORT = ACE_DEFAULT_SERVER_PORT;
-
-/*
- Finally, we get to main. Some C++ compilers will complain loudly if your
- function signature doesn't match the prototype. Even though we're not
- going to use the parameters, we still have to specify them.
- */
-
-int main (int argc, char *argv[])
-{
-/*
- In our earlier servers, we used a global pointer to get to the reactor. I've
- never really liked that idea, so I've moved it into main() this time. When
- we get to the Client_Handler object you'll see how we manage to get a
- pointer back to this reactor.
- */
- ACE_Reactor reactor;
-
- /*
- The acceptor will take care of letting clients connect to us. It will
- also arrange for a Client_Handler to be created for each new client.
- Since we're only going to listen at one TCP/IP port, we only need one
- acceptor. If we wanted, though, we could create several of these and
- listen at several ports. (That's what we would do if we wanted to rewrite
- inetd for instance.)
- */
- Client_Acceptor peer_acceptor;
-
- /*
- Create an ACE_INET_Addr that represents our endpoint of a connection. We
- then open our acceptor object with that Addr. Doing so tells the acceptor
- where to listen for connections. Servers generally listen at "well known"
- addresses. If not, there must be some mechanism by which the client is
- informed of the server's address.
-
- Note how ACE_ERROR_RETURN is used if we fail to open the acceptor. This
- technique is used over and over again in our tutorials.
- */
- if (peer_acceptor.open (ACE_INET_Addr (PORT), &reactor) == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1);
-
- /*
- Install our signal handler. You can actually register signal handlers
- with the reactor. You might do that when the signal handler is
- responsible for performing "real" work. Our simple flag-setter doesn't
- justify deriving from ACE_Event_Handler and providing a callback function
- though.
- */
- ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);
-
- /*
- Like ACE_ERROR_RETURN, the ACE_DEBUG macro gets used quite a bit. It's a
- handy way to generate uniform debug output from your program.
- */
- ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server daemon\n"));
-
- /*
- This will loop "forever" invoking the handle_events() method of our
- reactor. handle_events() watches for activity on any registered handlers
- and invokes their appropriate callbacks when necessary. Callback-driven
- programming is a big thing in ACE, you should get used to it. If the
- signal handler catches something, the finished flag will be set and we'll
- exit. Conveniently enough, handle_events() is also interrupted by signals
- and will exit back to the while() loop. (If you want your event loop to
- not be interrupted by signals, checkout the <i>restart</i> flag on the
- open() method of ACE_Reactor if you're interested.)
- */
- while (!finished)
- reactor.handle_events ();
-
- ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server daemon\n"));
-
- return 0;
-}
-
-#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-template class ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>;
-template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
-template class ACE_Guard<ACE_Mutex>;
-template class ACE_Atomic_Op<ACE_Mutex, int>;
-#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-#pragma instantiate ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>
-#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
-#pragma instantiate ACE_Guard<ACE_Mutex>
-#pragma instantiate ACE_Atomic_Op<ACE_Mutex, int>
-#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/docs/tutorials/007/thread_pool.cpp b/docs/tutorials/007/thread_pool.cpp
deleted file mode 100644
index 852b51ef232..00000000000
--- a/docs/tutorials/007/thread_pool.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-
-// $Id$
-
-#include "thread_pool.h"
-
-/*
- We need this header so that we can invoke handle_input() on the objects we dequeue.
- */
-#include "ace/Event_Handler.h"
-
-
-/*
- All we do here is initialize our active thread counter.
- */
-Thread_Pool::Thread_Pool(void)
- : active_threads_(0)
-{
-}
-
-/*
- Our open() method is a thin disguise around the ACE_Task<> activate() method. By
- hiding activate() in this way, the users of Thread_Pool don't have to worry about
- the thread configuration flags.
- */
-int Thread_Pool::open( int _pool_size )
-{
- return this->activate(THR_NEW_LWP,_pool_size);
-}
-
-/*
- Closing the thread pool can be a tricky exercise. I've decided to take an easy approach
- and simply enqueue a secret message for each thread we have active.
- */
-int Thread_Pool::close( u_long flags )
-{
- ACE_UNUSED_ARG(flags);
-
- /*
- Find out how many threads are currently active
- */
- int counter = active_threads_.value();
-
- /*
- For each one of the active threads, enqueue a "null" event handler. Below, we'll
- teach our svc() method that "null" means "shutdown".
- */
- while( counter-- )
- {
- this->enqueue( 0 );
- }
-
- /*
- As each svc() method exits, it will decrement the active thread counter. We just wait
- here for it to reach zero. Since we don't know how long it will take, we sleep for
- a quarter-second or so between tries.
- */
- while( active_threads_.value() )
- {
- ACE_OS::sleep( ACE_Time_Value(0.25) );
- }
-
- return(0);
-}
-
-/*
- When an object wants to do work in the pool, it should call the enqueue() method.
- We introduce the ACE_Message_Block here but, unfortunately, we seriously missuse it.
- */
-int Thread_Pool::enqueue( ACE_Event_Handler * _handler )
-{
- /*
- An ACE_Message_Block is a chunk of data. You put them into an ACE_Message_Queue.
- ACE_Task<> has an ACE_Message_Queue built in. In fact, the parameter to ACE_Task<>
- is passed directly to ACE_Message_Queue. If you look back at our header file you'll
- see that we used ACE_MT_SYNCH as the parameter indicating that we want MultiThread
- Synch safety. This allows us to safely put ACE_Message_Block objects into the
- message queue in one thread and take them out in another.
- */
-
- /*
- An ACE_Message_Block wants to have char* data. We don't have that. We could
- cast our ACE_Event_Handler* directly to a char* but I wanted to be more explicit.
- Since casting pointers around is a dangerous thing, I've gone out of my way here
- to be very clear about what we're doing.
-
- First: Cast the handler pointer to a void pointer. You can't do any useful work
- on a void pointer, so this is a clear message that we're making the
- pointer unusable.
-
- Next: Cast the void pointer to a char pointer that the ACE_Message_Block will accept.
- */
- void * v_data = (void*)_handler;
- char * c_data = (char*)v_data;
-
- /*
- Construct a new ACE_Message_Block. For efficiency, you might want to preallocate a
- stack of these and reuse them. For simplicity, I'll just create what I need as I need it.
- */
- ACE_Message_Block * mb = new ACE_Message_Block( c_data );
-
- /*
- Our putq() method is a wrapper around one of the enqueue methods of the ACE_Message_Queue
- that we own. Like all good methods, it returns -1 if it fails for some reason.
- */
- if( this->putq(mb) == -1 )
- {
- /*
- Another trait of the ACE_Message_Block objects is that they are reference counted.
- Since they're designed to be passed around between various objects in several threads
- we can't just delete them whenever we feel like it. The release() method is similar
- to the destroy() method we've used elsewhere. It watches the reference count and will
- delete the object when possible.
- */
- mb->release();
- return(-1);
- }
-
- return(0);
-}
-
-/*
- The "guard" concept is very powerful and used throughout multi-threaded applications.
- A guard normally does some operation on an object at construction and the "opposite"
- operation at destruction. For instance, when you guard a mutex (lock) object, the guard
- will acquire the lock on construction and release it on destruction. In this way, your
- method can simply let the guard go out of scope and know that the lock is released.
-
- Guards aren't only useful for locks however. In this application I've created two guard
- objects for quite a different purpose.
- */
-
-/*
- The Counter_Guard is constructed with a reference to the thread pool's active thread
- counter. The guard increments the counter when it is created and decrements it at
- destruction. By creating one of these in svc(), I know that the counter will be decremented
- no matter how or where svc() returns.
- */
-class Counter_Guard
-{
-public:
- Counter_Guard( Thread_Pool::counter_t & _counter )
- : counter_(_counter)
- {
- ++counter_;
- }
-
- ~Counter_Guard(void)
- {
- --counter_;
- }
-
-protected:
- Thread_Pool::counter_t & counter_;
-};
-
-/*
- My Message_Block_Guard is also a little non-traditional. It doesn't do anything in the
- constructor but it's destructor ensures that the message block's release() method is called.
- This is a cheap way to prevent a memory leak if I need an additional exit point in svc().
- */
-class Message_Block_Guard
-{
-public:
- Message_Block_Guard( ACE_Message_Block * & _mb )
- : mb_(_mb)
- {
- }
-
- ~Message_Block_Guard( void )
- {
- mb_->release();
- }
-
-protected:
- ACE_Message_Block * & mb_;
-};
-
-/*
- Now we come to the svc() method. As I said, this is being executed in each thread of the
- Thread_Pool. Here, we pull messages off of our built-in ACE_Message_Queue and cause them
- to do work.
- */
-int Thread_Pool::svc(void)
-{
- /*
- The getq() method takes a reference to a pointer. So... we need a pointer to give it
- a reference to.
- */
- ACE_Message_Block * mb;
-
- /*
- Create the guard for our active thread counter object. No matter where we choose to
- return() from svc(), we no know that the counter will be decremented.
- */
- Counter_Guard counter_guard(active_threads_);
-
- /*
- Get messages from the queue until we have a failure. There's no real good reason
- for failure so if it happens, we leave immediately.
- */
- while( this->getq(mb) != -1 )
- {
- /*
- A successful getq() will cause "mb" to point to a valid refernce-counted
- ACE_Message_Block. We use our guard object here so that we're sure to call
- the release() method of that message block and reduce it's reference count.
- Once the count reaches zero, it will be deleted.
- */
- Message_Block_Guard message_block_guard(mb);
-
- /*
- As noted before, the ACE_Message_Block stores it's data as a char*. We pull that
- out here and later turn it into an ACE_Event_Handler*
- */
- char * c_data = mb->base();
-
- /*
- We've chosen to use a "null" value as an indication to leave. If the data we got
- from the queue is not null then we have some work to do.
- */
- if( c_data )
- {
- /*
- Once again, we go to great lengths to emphasize the fact that we're casting pointers
- around in rather impolite ways. We could have cast the char* directly to an
- ACE_Event_Handler* but then folks might think that's an OK thing to do.
-
- (Note: The correct way to use an ACE_Message_Block is to write data into it.
- What I should have done was create a message block big enough to hold an
- event handler pointer and then written the pointer value into the block. When
- we got here, I would have to read that data back into a pointer. While politically
- correct, it is also a lot of work. If you're careful you can get away with casting
- pointers around.)
- */
- void * v_data = (void*)c_data;
-
- ACE_Event_Handler * handler = (ACE_Event_Handler*)v_data;
-
- /*
- Now that we finally have an event handler pointer, invoke it's handle_input() method.
- Since we don't know it's handle, we just give it a default. That's OK because we
- know that we're not using the handle in the method anyway.
- */
- if( handler->handle_input(ACE_INVALID_HANDLE) == -1 )
- {
- /*
- Tell the handler that it's time to go home. The "normal" method for shutting
- down a handler whose handler failed is to invoke handle_close(). This will
- take care of cleaning it up for us.
- Notice how we use the handler's get_handle() method to populate it's "handle"
- parameter. Convenient isn't it?
- */
- handler->handle_close(handler->get_handle(),0);
-
- /*
- Also notice that we don't exit the svc() method here! The first time I did
- this, I was exiting. After a few clients disconnect you have an empty
- thread pool. Hard to do any more work after that...
- */
- }
- }
- else
- {
- /*
- If we get here, we were given a message block with "null" data. That is our
- signal to leave, so we return(0) to leave gracefully.
- */
- return(0); // Ok, shutdown request
- }
-
- // message_block_guard goes out of scope here
- // and releases the message_block instance.
- }
-
- return(0);
-}
-
diff --git a/docs/tutorials/007/thread_pool.h b/docs/tutorials/007/thread_pool.h
deleted file mode 100644
index 12b9f14a44f..00000000000
--- a/docs/tutorials/007/thread_pool.h
+++ /dev/null
@@ -1,102 +0,0 @@
-
-// $Id$
-
-#ifndef THREAD_POOL_H
-#define THREAD_POOL_H
-
-/*
- In order to implement a thread pool, we have to have an object that can create
- a thread. The ACE_Task<> is the basis for doing just such a thing.
- */
-#include "ace/Task.h"
-
-#if !defined (ACE_LACKS_PRAGMA_ONCE)
-# pragma once
-#endif /* ACE_LACKS_PRAGMA_ONCE */
-
-/*
- We need a forward reference for ACE_Event_Handler so that our enqueue() method
- can accept a pointer to one.
- */
-class ACE_Event_Handler;
-
-/*
- Although we modified the rest of our program to make use of the thread pool
- implementation, if you look closely you'll see that the changes were rather
- minor. The "ACE way" is generally to create a helper object that abstracts
- away the details not relevant to your application. That's what I'm trying
- to do here by creating the Thread_Pool object.
- */
-class Thread_Pool : public ACE_Task<ACE_MT_SYNCH>
-{
-public:
-
- typedef ACE_Task<ACE_MT_SYNCH> inherited;
-
- /*
- Provide an enumeration for the default pool size. By doing this, other objects
- can use the value when they want a default.
- */
- enum size_t
- {
- default_pool_size_ = 5
- };
-
- // Basic constructor
- Thread_Pool(void);
-
- /*
- Opening the thread pool causes one or more threads to be activated. When activated,
- they all execute the svc() method declared below.
- */
- int open( int _pool_size = default_pool_size_ );
-
- /*
- Some compilers will complain that our open() above attempts to
- override a virtual function in the baseclass. We have no
- intention of overriding that method but in order to keep the
- compiler quiet we have to add this method as a pass-thru to the
- baseclass method.
- */
- virtual int open(void * _void_data)
- { return inherited::open(_void_data); }
-
- /*
- */
- int close( u_long flags = 0 );
-
- /*
- To use the thread pool, you have to put some unit of work into it. Since we're
- dealing with event handlers (or at least their derivatives), I've chosen to provide
- an enqueue() method that takes a pointer to an ACE_Event_Handler. The handler's
- handle_input() method will be called, so your object has to know when it is being
- called by the thread pool.
- */
- int enqueue( ACE_Event_Handler * _handler );
-
- /*
- Another handy ACE template is ACE_Atomic_Op<>. When parameterized, this allows
- is to have a thread-safe counting object. The typical arithmetic operators are
- all internally thread-safe so that you can share it across threads without worrying
- about any contention issues.
- */
- typedef ACE_Atomic_Op<ACE_Mutex,int> counter_t;
-
-protected:
-
- /*
- Our svc() method will dequeue the enqueued event handler objects and invoke the
- handle_input() method on each. Since we're likely running in more than one thread,
- idle threads can take work from the queue while other threads are busy executing
- handle_input() on some object.
- */
- int svc(void);
-
- /*
- We use the atomic op to keep a count of the number of threads in which our svc()
- method is running. This is particularly important when we want to close() it down!
- */
- counter_t active_threads_;
-};
-
-#endif // THREAD_POOL_H