diff options
Diffstat (limited to 'docs/tutorials/007/page06.html')
-rw-r--r-- | docs/tutorials/007/page06.html | 365 |
1 files changed, 0 insertions, 365 deletions
diff --git a/docs/tutorials/007/page06.html b/docs/tutorials/007/page06.html deleted file mode 100644 index f4e14834b49..00000000000 --- a/docs/tutorials/007/page06.html +++ /dev/null @@ -1,365 +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. Just a few -though. - -<P> -<HR WIDTH="100%"> -<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 -we've seen most of this, I'm going to strip out almost</FONT> -<BR><FONT FACE="Arial,Helvetica"> all of the comments that -you've already seen. That way, you can concentrate on the</FONT> -<BR><FONT FACE="Arial,Helvetica"> new items.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">#include "client_acceptor.h"</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"> We're going to be registering -and unregistering a couple of times. To make sure that</FONT> -<BR><FONT FACE="Arial,Helvetica"> we use the same flags every -time, I've created these handy macros.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">#define REGISTER_MASK -ACE_Event_Handler::READ_MASK</FONT> -<BR><FONT FACE="Arial,Helvetica">#define REMOVE_MASK -(ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL)</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Our constructor still doesn't -really do anything. We simply initialize the acceptor</FONT> -<BR><FONT FACE="Arial,Helvetica"> pointer to "null" and get -our current thread id. The static self() method of ACE_Thread</FONT> -<BR><FONT FACE="Arial,Helvetica"> will return you a thread -id native to your platform.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">Client_Handler::Client_Handler (void)</FONT> -<BR><FONT FACE="Arial,Helvetica"> : client_acceptor_(0)</FONT> -<BR><FONT FACE="Arial,Helvetica"> ,creator_(ACE_Thread::self())</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">Client_Handler::~Client_Handler (void)</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"> Query our acceptor for the -concurrency strategy. Notice that we don't bother</FONT> -<BR><FONT FACE="Arial,Helvetica"> to check that our acceptor -pointer is valid. That is proably a bad idea...</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Client_Handler::concurrency(void)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return this->client_acceptor()->concurrency();</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> And here we ask the acceptor -about the thread pool.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">Thread_Pool * Client_Handler::thread_pool(void)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return this->client_acceptor()->thread_pool();</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> The destroy() method hasn't -changed since we wrote it back in Tutorial 5.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">void Client_Handler::destroy (void)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> this->peer ().close ();</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> this->reactor ()->remove_handler -(this, REMOVE_MASK );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> delete this;</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Back to our open() method. -This is straight out of Tutorial 6. There's</FONT> -<BR><FONT FACE="Arial,Helvetica"> nothing additional here for -the thread-pool implementation.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Client_Handler::open (void *_acceptor)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> client_acceptor( (Client_Acceptor -*) _acceptor );</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> if( concurrency() == Client_Acceptor::thread_per_connection_ -)</FONT> -<BR><FONT FACE="Arial,Helvetica"> {</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return this->activate();</FONT> -<BR><FONT FACE="Arial,Helvetica"> }</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> this->reactor (client_acceptor()->reactor -());</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> ACE_INET_Addr addr;</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> if (this->peer ().get_remote_addr -(addr) == -1)</FONT> -<BR><FONT FACE="Arial,Helvetica"> {</FONT> -<BR><FONT FACE="Arial,Helvetica"> return --1;</FONT> -<BR><FONT FACE="Arial,Helvetica"> }</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> if (this->reactor ()->register_handler -(this, REGISTER_MASK) == -1)</FONT> -<BR><FONT FACE="Arial,Helvetica"> {</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_ERROR_RETURN -((LM_ERROR, "(%P|%t) can't register with reactor\n"), -1);</FONT> -<BR><FONT FACE="Arial,Helvetica"> }</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected -with %s\n", addr.get_host_name ()));</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> - -<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 -to be read. When the reactor sees that activity</FONT> -<BR><FONT FACE="Arial,Helvetica"> it will invoke this handle_input() -method on us. As I mentioned, the _handle</FONT> -<BR><FONT FACE="Arial,Helvetica"> parameter isn't useful to -us but it narrows the list of methods the reactor</FONT> -<BR><FONT FACE="Arial,Helvetica"> has to worry about and the -list of possible virtual functions we would have</FONT> -<BR><FONT FACE="Arial,Helvetica"> to override.</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> You've read that much before... -Now we have to do some extra stuff in case</FONT> -<BR><FONT FACE="Arial,Helvetica"> we're using the thread-pool -implementation. If we're called by our creator</FONT> -<BR><FONT FACE="Arial,Helvetica"> thread then we must be in -the reactor. In that case, we arrange to be put</FONT> -<BR><FONT FACE="Arial,Helvetica"> into the thread pool. -If we're not in the creator thread then we must be</FONT> -<BR><FONT FACE="Arial,Helvetica"> in the thread pool and we -can do some work.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Client_Handler::handle_input (ACE_HANDLE -_handle)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_UNUSED_ARG (_handle);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Check our strategy. -If we're using the thread pool and we're in the creation</FONT> -<BR><FONT FACE="Arial,Helvetica"> -thread then we know we were called by the reactor.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> if( concurrency() == Client_Acceptor::thread_pool_ -)</FONT> -<BR><FONT FACE="Arial,Helvetica"> {</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( ACE_Thread::self() == creator_ )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> -Remove ourselves from the reactor and ask to be put into the thread pool's</FONT> -<BR><FONT FACE="Arial,Helvetica"> -queue of work. (You should be able to use suspend_handler() but I've -had</FONT> -<BR><FONT FACE="Arial,Helvetica"> -problems with that.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> -*/</FONT> -<BR><FONT FACE="Arial,Helvetica"> -this->reactor()->remove_handler( this, REMOVE_MASK );</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return this->thread_pool()->enqueue(this);</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"> Any strategy -other than thread-per-connection will eventually get here. If we're -in the</FONT> -<BR><FONT FACE="Arial,Helvetica"> -single-threaded implementation or the thread-pool, we still have to pass -this way.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> char buf[128];</FONT> -<BR><FONT FACE="Arial,Helvetica"> memset (buf, 0, sizeof (buf));</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Invoke the process() -method to do the work but save it's return value instead</FONT> -<BR><FONT FACE="Arial,Helvetica"> -of returning it immediately.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> int rval = this->process(buf,sizeof(buf));</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> /*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Now, we look -again to see if we're in the thread-pool implementation. If so then -we</FONT> -<BR><FONT FACE="Arial,Helvetica"> -need to re-register ourselves with the reactor so that we can get more -work when it</FONT> -<BR><FONT FACE="Arial,Helvetica"> -is available. (If suspend_handler() worked then we would use resume_handler() -here.)</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> if( concurrency() == Client_Acceptor::thread_pool_ -)</FONT> -<BR><FONT FACE="Arial,Helvetica"> {</FONT> -<BR><FONT FACE="Arial,Helvetica"> -if( rval != -1 )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -this->reactor()->register_handler( this, REGISTER_MASK );</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"> Return the result -of process()</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica"> return(rval);</FONT> -<BR><FONT FACE="Arial,Helvetica">}</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica">int Client_Handler::handle_close (ACE_HANDLE -_handle, ACE_Reactor_Mask _mask)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_UNUSED_ARG (_handle);</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_UNUSED_ARG (_mask);</FONT><FONT FACE="Arial,Helvetica"></FONT> - -<P><FONT FACE="Arial,Helvetica"> this->destroy ();</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">/*</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> - -<P><FONT FACE="Arial,Helvetica"> while( 1 )</FONT> -<BR><FONT FACE="Arial,Helvetica"> {</FONT> -<BR><FONT FACE="Arial,Helvetica"> if( this->process(buf,sizeof(buf)) -== -1 )</FONT> -<BR><FONT FACE="Arial,Helvetica"> -{</FONT> -<BR><FONT FACE="Arial,Helvetica"> -return(-1);</FONT> -<BR><FONT FACE="Arial,Helvetica"> }</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> - -<P><FONT FACE="Arial,Helvetica">/*</FONT> -<BR><FONT FACE="Arial,Helvetica"> Once again, we see that the -application-level logic has not been at all affected</FONT> -<BR><FONT FACE="Arial,Helvetica"> by our choice of threading -models. Of course, I'm not sharing data between threads</FONT> -<BR><FONT FACE="Arial,Helvetica"> or anything. We'll -leave locking issues for a later tutorial.</FONT> -<BR><FONT FACE="Arial,Helvetica"> */</FONT> -<BR><FONT FACE="Arial,Helvetica">int Client_Handler::process (char *_rdbuf, -int _rdbuf_len)</FONT> -<BR><FONT FACE="Arial,Helvetica">{</FONT> -<BR><FONT FACE="Arial,Helvetica"> switch (this->peer ().recv (_rdbuf, -_rdbuf_len))</FONT> -<BR><FONT FACE="Arial,Helvetica"> {</FONT> -<BR><FONT FACE="Arial,Helvetica"> case -1:</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_ERROR_RETURN -((LM_ERROR, "(%P|%t) %p bad read\n", "client"), -1);</FONT> -<BR><FONT FACE="Arial,Helvetica"> case 0:</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_ERROR_RETURN -((LM_ERROR, "(%P|%t) closing daemon (fd = %d)\n", this->get_handle ()), --1);</FONT> -<BR><FONT FACE="Arial,Helvetica"> default:</FONT> -<BR><FONT FACE="Arial,Helvetica"> ACE_DEBUG -((LM_DEBUG, "(%P|%t) from client: %s", _rdbuf));</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> - -<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> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>] [<A HREF="page07.html">Continue -This Tutorial</A>]</CENTER> - -</BODY> -</HTML> |