diff options
author | jcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-09-01 03:51:50 +0000 |
---|---|---|
committer | jcej <jcej@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-09-01 03:51:50 +0000 |
commit | b18c5aafd6f58154f82f1cbf376b371a241e6a04 (patch) | |
tree | 4802caa85de20b17e726dbcfbb682e0f63c5c78c /docs/tutorials/007 | |
parent | 1b1d47130a30c7f641e489ac65d3820e87783e77 (diff) | |
download | ATCD-b18c5aafd6f58154f82f1cbf376b371a241e6a04.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/tutorials/007')
-rw-r--r-- | docs/tutorials/007/client_handler.cpp | 21 | ||||
-rw-r--r-- | docs/tutorials/007/client_handler.h | 8 | ||||
-rw-r--r-- | docs/tutorials/007/page05.html | 26 | ||||
-rw-r--r-- | docs/tutorials/007/page06.html | 57 | ||||
-rw-r--r-- | docs/tutorials/007/page08.html | 64 | ||||
-rw-r--r-- | docs/tutorials/007/page09.html | 2 | ||||
-rw-r--r-- | docs/tutorials/007/thread_pool.cpp | 15 |
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> <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> +<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 < 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"> typedef ACE_Svc_Handler < ACE_SOCK_STREAM, +ACE_NULL_SYNCH > inherited;</FONT><FONT FACE="Arial,Helvetica"></FONT> <P><FONT FACE="Arial,Helvetica"> // Constructor...</FONT> <BR><FONT FACE="Arial,Helvetica"> 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"> int open (void *_acceptor);</FONT><FONT FACE="Arial,Helvetica"></FONT> <P><FONT FACE="Arial,Helvetica"> /*</FONT> +<BR><FONT FACE="Arial,Helvetica"> When an ACE_Task<> +object falls out of the svc() method, the framework</FONT> +<BR><FONT FACE="Arial,Helvetica"> will call the +close() method. That's where we want to cleanup ourselves</FONT> +<BR><FONT FACE="Arial,Helvetica"> if we're running +in either thread-per-connection or thread-pool mode.</FONT> +<BR><FONT FACE="Arial,Helvetica"> */</FONT> +<BR><FONT FACE="Arial,Helvetica"> int close(u_long flags = 0);</FONT><FONT FACE="Arial,Helvetica"></FONT> + +<P><FONT FACE="Arial,Helvetica"> /*</FONT> <BR><FONT FACE="Arial,Helvetica"> When there is activity on a registered handler, the handle_input() method</FONT> <BR><FONT FACE="Arial,Helvetica"> of the handler @@ -264,7 +275,7 @@ one of the thread pool threads. 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. Just a few though. +<P><A HREF="client_handler.cpp">client_handler.cpp</A> +shows some of the changes due to the thread-pool. Just a few +though. <P> <HR WIDTH="100%"> -<BR><FONT FACE="Arial,Helvetica"></FONT> <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> +<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"> 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"> As mentioned in the header, +the typical way to close an object in a threaded</FONT> +<BR><FONT FACE="Arial,Helvetica"> context is to invoke it's +close() method. Since we already have a handle_close()</FONT> +<BR><FONT FACE="Arial,Helvetica"> method built to cleanup after +us, we'll just forward the request on to that</FONT> +<BR><FONT FACE="Arial,Helvetica"> object.</FONT> +<BR><FONT FACE="Arial,Helvetica"> */</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"> +this->handle_close(ACE_INVALID_HANDLE,0);</FONT><FONT FACE="Arial,Helvetica"></FONT> + +<P><FONT FACE="Arial,Helvetica"> +/*</FONT> +<BR><FONT FACE="Arial,Helvetica"> +After we've taken care of ourselves, call the baseclass method</FONT> +<BR><FONT FACE="Arial,Helvetica"> +to do any other necessary cleanup.</FONT> +<BR><FONT FACE="Arial,Helvetica"> +*/</FONT> +<BR><FONT FACE="Arial,Helvetica"> +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"> In the open() method, we registered with the reactor and requested to be</FONT> <BR><FONT FACE="Arial,Helvetica"> notified when there is data @@ -268,7 +294,13 @@ _handle, ACE_Reactor_Mask _mask)</FONT> <BR><FONT FACE="Arial,Helvetica"> 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"> Remember that when we leave +our svc() method, the framework will take care</FONT> +<BR><FONT FACE="Arial,Helvetica"> of calling our close() method +so that we can cleanup after ourselves.</FONT> +<BR><FONT FACE="Arial,Helvetica"> */</FONT> +<BR><FONT FACE="Arial,Helvetica">int Client_Handler::svc(void)</FONT> <BR><FONT FACE="Arial,Helvetica">{</FONT> <BR><FONT FACE="Arial,Helvetica"> char buf[128];</FONT> <BR><FONT FACE="Arial,Helvetica"> memset (buf, 0, sizeof (buf));</FONT><FONT FACE="Arial,Helvetica"></FONT> @@ -314,18 +346,19 @@ _rdbuf_len))</FONT> <BR><FONT FACE="Arial,Helvetica"> }</FONT><FONT FACE="Arial,Helvetica"></FONT> <P><FONT FACE="Arial,Helvetica"> return 0;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> +<BR><FONT FACE="Arial,Helvetica">}</FONT> <P> <HR WIDTH="100%"> -<P>Ok, now we've gone and changed handle_input() so that it knows -when to do work and when to enqueue itself. Beyond that, we're still -about the same. +<P>Ok, now we've gone and changed handle_input() so that it knows when +to do work and when to enqueue itself. Beyond that, we're still about +the same. <P> <HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial Index</A>] [<A HREF="page07.html">Continue +<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"> First: Cast the handler pointer to a void pointer. You can't do any useful work</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> on a void pointer, so this is a clear message that we're making the</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> pointer unusable.</FONT><FONT FACE="Arial,Helvetica"></FONT> <P><FONT FACE="Arial,Helvetica"> @@ -211,16 +211,16 @@ if( this->putq(mb) == -1 )</FONT> <BR><FONT FACE="Arial,Helvetica"> Another trait of the ACE_Message_Block objects is that they are reference counted.</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> Since they're designed to be passed around between various objects in several threads</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> we can't just delete them whenever we feel like it. The release() method is similar</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> to the destroy() method we've used elsewhere. It watches the reference count and will</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> delete the object when possible.</FONT> <BR><FONT FACE="Arial,Helvetica"> */</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"> (Note: The correct way to use an ACE_Message_Block is to write data into it.</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> What I should have done was create a message block big enough to hold an</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> event handler pointer and then written the pointer value into the block. When</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> we got here, I would have to read that data back into a pointer. While politically</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> correct, it is also a lot of work. If you're careful you can get away with casting</FONT> -<BR><FONT FACE="Arial,Helvetica"> +<BR><FONT FACE="Arial,Helvetica"> pointers around.)</FONT> <BR><FONT FACE="Arial,Helvetica"> */</FONT> @@ -464,7 +464,35 @@ if( handler->handle_input(ACE_INVALID_HANDLE) == -1 )</FONT> <BR><FONT FACE="Arial,Helvetica"> {</FONT> <BR><FONT FACE="Arial,Helvetica"> -return(-1); // Error, return now</FONT> +/*</FONT> +<BR><FONT FACE="Arial,Helvetica"> +Tell the handler that it's time to go home. The "normal" method for +shutting</FONT> +<BR><FONT FACE="Arial,Helvetica"> +down a handler whose handler failed is to invoke handle_close(). +This will</FONT> +<BR><FONT FACE="Arial,Helvetica"> +take care of cleaning it up for us.</FONT> +<BR><FONT FACE="Arial,Helvetica"> +Notice how we use the handler's get_handle() method to populate it's "handle"</FONT> +<BR><FONT FACE="Arial,Helvetica"> +parameter. Convenient isn't it?</FONT> +<BR><FONT FACE="Arial,Helvetica"> +*/</FONT> +<BR><FONT FACE="Arial,Helvetica"> +handler->handle_close(handler->get_handle(),0);</FONT><FONT FACE="Arial,Helvetica"></FONT> + +<P><FONT FACE="Arial,Helvetica"> +/*</FONT> +<BR><FONT FACE="Arial,Helvetica"> +Also notice that we don't exit the svc() method here! The first time +I did</FONT> +<BR><FONT FACE="Arial,Helvetica"> +this, I was exiting. After a few clients disconnect you have an empty</FONT> +<BR><FONT FACE="Arial,Helvetica"> +thread pool. Hard to do any more work after that...</FONT> +<BR><FONT FACE="Arial,Helvetica"> +*/</FONT> <BR><FONT FACE="Arial,Helvetica"> }</FONT> <BR><FONT FACE="Arial,Helvetica"> @@ -498,11 +526,11 @@ return(0); &nbs <P><FONT FACE="Arial,Helvetica"> return(0);</FONT> <BR><FONT FACE="Arial,Helvetica">}</FONT> -<BR><FONT FACE="Arial,Helvetica"></FONT> <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 |