summaryrefslogtreecommitdiff
path: root/docs/tutorials/007/page06.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/007/page06.html')
-rw-r--r--docs/tutorials/007/page06.html272
1 files changed, 0 insertions, 272 deletions
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>