summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorjcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-09-01 03:51:50 +0000
committerjcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-09-01 03:51:50 +0000
commit26694a3d80511f35e46088abe7a213a35e5d3d5a (patch)
tree4802caa85de20b17e726dbcfbb682e0f63c5c78c /docs
parent62406c009a227206988d7ca6ba078544de01a019 (diff)
downloadATCD-26694a3d80511f35e46088abe7a213a35e5d3d5a.tar.gz
Added Client_Handler::close() that will be called when Client_Handler::svc()
exits in the thread-per-connection model. Thread_Pool::svc() now calls the handler's handle_close() method to properly shut down the handler if handle_input() fails.
Diffstat (limited to 'docs')
-rw-r--r--docs/tutorials/007/client_handler.cpp21
-rw-r--r--docs/tutorials/007/client_handler.h8
-rw-r--r--docs/tutorials/007/page05.html26
-rw-r--r--docs/tutorials/007/page06.html57
-rw-r--r--docs/tutorials/007/page08.html64
-rw-r--r--docs/tutorials/007/page09.html2
-rw-r--r--docs/tutorials/007/thread_pool.cpp15
7 files changed, 154 insertions, 39 deletions
diff --git a/docs/tutorials/007/client_handler.cpp b/docs/tutorials/007/client_handler.cpp
index d14c8ce3144..457a11eed4c 100644
--- a/docs/tutorials/007/client_handler.cpp
+++ b/docs/tutorials/007/client_handler.cpp
@@ -94,6 +94,23 @@ int Client_Handler::open (void *_acceptor)
}
/*
+ As mentioned in the header, the typical way to close an object in a threaded
+ context is to invoke it's close() method. Since we already have a handle_close()
+ method built to cleanup after us, we'll just forward the request on to that
+ object.
+ */
+int Client_Handler::close(u_long flags)
+{
+ this->handle_close(ACE_INVALID_HANDLE,0);
+
+ /*
+ After we've taken care of ourselves, call the baseclass method
+ to do any other necessary cleanup.
+ */
+ return inherited::close();
+}
+
+/*
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
@@ -172,6 +189,10 @@ int Client_Handler::handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask)
return 0;
}
+/*
+ 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];
diff --git a/docs/tutorials/007/client_handler.h b/docs/tutorials/007/client_handler.h
index c86012d4b7b..340cde65a4d 100644
--- a/docs/tutorials/007/client_handler.h
+++ b/docs/tutorials/007/client_handler.h
@@ -30,6 +30,7 @@ class Thread_Pool;
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);
@@ -58,6 +59,13 @@ public:
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
diff --git a/docs/tutorials/007/page05.html b/docs/tutorials/007/page05.html
index 7e8df23e750..a5ad7a8d62e 100644
--- a/docs/tutorials/007/page05.html
+++ b/docs/tutorials/007/page05.html
@@ -21,10 +21,9 @@ is next.
<P>
<HR WIDTH="100%">
-<BR><FONT FACE="Arial,Helvetica"></FONT>&nbsp;<FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">// $Id: client_handler.h,v 1.1 1998/08/30
-16:04:12 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
+<BR>&nbsp;
+<BR><FONT FACE="Arial,Helvetica">// $Id: client_handler.h,v 1.1 1998/08/30
+23:47:14 schmidt Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
<P><FONT FACE="Arial,Helvetica">#ifndef CLIENT_HANDLER_H</FONT>
<BR><FONT FACE="Arial,Helvetica">#define CLIENT_HANDLER_H</FONT><FONT FACE="Arial,Helvetica"></FONT>
@@ -67,7 +66,9 @@ at concurrency options.</FONT>
<BR><FONT FACE="Arial,Helvetica">class Client_Handler : public ACE_Svc_Handler
&lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH ></FONT>
<BR><FONT FACE="Arial,Helvetica">{</FONT>
-<BR><FONT FACE="Arial,Helvetica">public:</FONT><FONT FACE="Arial,Helvetica"></FONT>
+<BR><FONT FACE="Arial,Helvetica">public:</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp; typedef ACE_Svc_Handler &lt; ACE_SOCK_STREAM,
+ACE_NULL_SYNCH > inherited;</FONT><FONT FACE="Arial,Helvetica"></FONT>
<P><FONT FACE="Arial,Helvetica">&nbsp; // Constructor...</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp; Client_Handler (void);</FONT><FONT FACE="Arial,Helvetica"></FONT>
@@ -110,6 +111,16 @@ open() you'll see how we get around that.</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp; int open (void *_acceptor);</FONT><FONT FACE="Arial,Helvetica"></FONT>
<P><FONT FACE="Arial,Helvetica">&nbsp; /*</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; When an ACE_Task&lt;>
+object falls out of the svc() method, the framework</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; will call the
+close() method.&nbsp; That's where we want to cleanup ourselves</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; if we're running
+in either thread-per-connection or thread-pool mode.</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; */</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp; int close(u_long flags = 0);</FONT><FONT FACE="Arial,Helvetica"></FONT>
+
+<P><FONT FACE="Arial,Helvetica">&nbsp; /*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; When there is
activity on a registered handler, the handle_input() method</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp; of the handler
@@ -264,7 +275,7 @@ one of the thread pool threads.&nbsp; More on this when we get to handle_input()
creator_;</FONT>
<BR><FONT FACE="Arial,Helvetica">};</FONT><FONT FACE="Arial,Helvetica"></FONT>
-<P><FONT FACE="Arial,Helvetica">#endif // CLIENT_HANDLER_H</FONT><FONT FACE="Arial,Helvetica"></FONT>
+<P><FONT FACE="Arial,Helvetica">#endif // CLIENT_HANDLER_H</FONT>
<P>
<HR WIDTH="100%">
@@ -275,7 +286,8 @@ 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
+<CENTER>[<A HREF="..">Tutorial
+Index</A>] [<A HREF="page06.html">Continue
This Tutorial</A>]</CENTER>
</BODY>
diff --git a/docs/tutorials/007/page06.html b/docs/tutorials/007/page06.html
index 605cc80a03f..f4e14834b49 100644
--- a/docs/tutorials/007/page06.html
+++ b/docs/tutorials/007/page06.html
@@ -16,15 +16,15 @@
<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><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%">
-<BR><FONT FACE="Arial,Helvetica"></FONT>&nbsp;<FONT FACE="Arial,Helvetica"></FONT>
-
-<P><FONT FACE="Arial,Helvetica">// $Id: client_handler.cpp,v 1.1 1998/08/30
-16:04:12 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
+<BR>&nbsp;
+<BR><FONT FACE="Arial,Helvetica">// $Id: client_handler.cpp,v 1.1 1998/08/30
+23:47:14 schmidt Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
<P><FONT FACE="Arial,Helvetica">/*</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Since this is the third time
@@ -146,6 +146,32 @@ with %s\n", addr.get_host_name ()));</FONT><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; As mentioned in the header,
+the typical way to close an object in a threaded</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; context is to invoke it's
+close() method.&nbsp; Since we already have a handle_close()</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; method built to cleanup after
+us, we'll just forward the request on to that</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; object.</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
+<BR><FONT FACE="Arial,Helvetica">int Client_Handler::close(u_long flags)</FONT>
+<BR><FONT FACE="Arial,Helvetica">{</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+this->handle_close(ACE_INVALID_HANDLE,0);</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;
+After we've taken care of ourselves, call the baseclass method</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+to do any other necessary cleanup.</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;
+return inherited::close();</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; In the open() method, we
registered with the reactor and requested to be</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; notified when there is data
@@ -268,7 +294,13 @@ _handle, ACE_Reactor_Mask _mask)</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp; return 0;</FONT>
<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
-<P><FONT FACE="Arial,Helvetica">int Client_Handler::svc(void)</FONT>
+<P><FONT FACE="Arial,Helvetica">/*</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; Remember that when we leave
+our svc() method, the framework will take care</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp; of calling our close() method
+so that we can cleanup after ourselves.</FONT>
+<BR><FONT FACE="Arial,Helvetica">&nbsp;*/</FONT>
+<BR><FONT FACE="Arial,Helvetica">int Client_Handler::svc(void)</FONT>
<BR><FONT FACE="Arial,Helvetica">{</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp; char buf[128];</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp; memset (buf, 0, sizeof (buf));</FONT><FONT FACE="Arial,Helvetica"></FONT>
@@ -314,18 +346,19 @@ _rdbuf_len))</FONT>
<BR><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp; }</FONT><FONT FACE="Arial,Helvetica"></FONT>
<P><FONT FACE="Arial,Helvetica">&nbsp; return 0;</FONT>
-<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT>
+<BR><FONT FACE="Arial,Helvetica">}</FONT>
<P>
<HR WIDTH="100%">
-<P>Ok, now we've gone and changed handle_input()&nbsp;so that it knows
-when to do work and when to enqueue itself.&nbsp; Beyond that, we're still
-about the same.
+<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
+<CENTER>[<A HREF="..">Tutorial
+Index</A>] [<A HREF="page07.html">Continue
This Tutorial</A>]</CENTER>
</BODY>
diff --git a/docs/tutorials/007/page08.html b/docs/tutorials/007/page08.html
index 5c3ede6e8ab..094804e743d 100644
--- a/docs/tutorials/007/page08.html
+++ b/docs/tutorials/007/page08.html
@@ -16,14 +16,14 @@
<P>
<HR WIDTH="100%">
-<P>Finally, <A HREF="thread_pool.cpp">thread_pool.cpp</A> where we have
-the Thread_Pool object implementation.
+<P>Finally, <A HREF="thread_pool.cpp">thread_pool.cpp</A>
+where we have the Thread_Pool object implementation.
<P>
-<HR WIDTH="100%"><FONT FACE="Arial,Helvetica"></FONT>
+<HR WIDTH="100%">
<P><FONT FACE="Arial,Helvetica">// $Id: thread_pool.cpp,v 1.1 1998/08/30
-16:04:12 jcej Exp $</FONT><FONT FACE="Arial,Helvetica"></FONT>
+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>
@@ -164,9 +164,9 @@ to be very clear about what we're doing.</FONT><FONT FACE="Arial,Helvetica"></FO
<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;&nbsp;
+<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;
+<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;
@@ -211,16 +211,16 @@ if( this->putq(mb) == -1 )</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;
+<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;
+<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;
+<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;
+<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>
@@ -426,18 +426,18 @@ ACE_Event_Handler* but then folks might think that's an OK thing to do.</FONT><F
<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;&nbsp;&nbsp;&nbsp;&nbsp;
+<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;&nbsp;&nbsp;&nbsp;&nbsp;
+<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;&nbsp;&nbsp;&nbsp;&nbsp;
+<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;&nbsp;&nbsp;&nbsp;&nbsp;
+<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;&nbsp;&nbsp;&nbsp;&nbsp;
+<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>
@@ -464,7 +464,35 @@ 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;
-return(-1);&nbsp;&nbsp; // Error, return now</FONT>
+/*</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;
@@ -498,11 +526,11 @@ return(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs
<P><FONT FACE="Arial,Helvetica">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
return(0);</FONT>
<BR><FONT FACE="Arial,Helvetica">}</FONT>
-<BR><FONT FACE="Arial,Helvetica"></FONT>&nbsp;<FONT FACE="Arial,Helvetica"></FONT>
<P>
<HR WIDTH="100%">
-<CENTER>[<A HREF="..">Tutorial Index</A>] [<A HREF="page09.html">Continue
+<CENTER>[<A HREF="..">Tutorial
+Index</A>] [<A HREF="page09.html">Continue
This Tutorial</A>]</CENTER>
</BODY>
diff --git a/docs/tutorials/007/page09.html b/docs/tutorials/007/page09.html
index 5023e761eec..af87b79444c 100644
--- a/docs/tutorials/007/page09.html
+++ b/docs/tutorials/007/page09.html
@@ -48,7 +48,7 @@ to include it here.
<A HREF="thread_pool.h">thread_pool.h</A></LI>
<LI>
-<A HREF="thread_pool.cpp">thread_poo.cpp</A></LI>
+<A HREF="thread_pool.cpp">thread_pool.cpp</A></LI>
<LI>
<A HREF="fix.Makefile">fix.Makefile</A></LI>
diff --git a/docs/tutorials/007/thread_pool.cpp b/docs/tutorials/007/thread_pool.cpp
index dc2ff7f2a39..1b99776a517 100644
--- a/docs/tutorials/007/thread_pool.cpp
+++ b/docs/tutorials/007/thread_pool.cpp
@@ -241,7 +241,20 @@ int Thread_Pool::svc(void)
*/
if( handler->handle_input(ACE_INVALID_HANDLE) == -1 )
{
- return(-1); // Error, return now
+ /*
+ 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