summaryrefslogtreecommitdiff
path: root/docs/tutorials/007/page02.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/007/page02.html')
-rw-r--r--docs/tutorials/007/page02.html197
1 files changed, 197 insertions, 0 deletions
diff --git a/docs/tutorials/007/page02.html b/docs/tutorials/007/page02.html
new file mode 100644
index 00000000000..c6e7bedec43
--- /dev/null
+++ b/docs/tutorials/007/page02.html
@@ -0,0 +1,197 @@
+<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>