summaryrefslogtreecommitdiff
path: root/docs/tutorials
diff options
context:
space:
mode:
authorschmidt <douglascraigschmidt@users.noreply.github.com>1999-02-01 01:44:51 +0000
committerschmidt <douglascraigschmidt@users.noreply.github.com>1999-02-01 01:44:51 +0000
commit831c4d99ee0a47f53224f853894f1dc4671337d6 (patch)
treeccc0880a44bcb64eb941e4a9351604829608a674 /docs/tutorials
parente08a13353ca7e009c39cab4acaf09b831f492b4b (diff)
downloadATCD-831c4d99ee0a47f53224f853894f1dc4671337d6.tar.gz
.
Diffstat (limited to 'docs/tutorials')
-rw-r--r--docs/tutorials/001/page01.html19
-rw-r--r--docs/tutorials/001/page02.html20
-rw-r--r--docs/tutorials/001/page03.html20
-rw-r--r--docs/tutorials/001/page04.html23
-rw-r--r--docs/tutorials/001/page05.html17
-rw-r--r--docs/tutorials/002/page03.html195
-rw-r--r--docs/tutorials/005/page03.html45
-rw-r--r--docs/tutorials/005/page04.html158
-rw-r--r--docs/tutorials/006/page01.html2
-rw-r--r--docs/tutorials/006/page03.html113
-rw-r--r--docs/tutorials/006/page04.html190
-rw-r--r--docs/tutorials/007/page01.html3
-rw-r--r--docs/tutorials/007/page03.html210
-rw-r--r--docs/tutorials/007/page05.html268
-rw-r--r--docs/tutorials/007/page07.html145
-rw-r--r--docs/tutorials/014/page02.html47
-rw-r--r--docs/tutorials/014/page04.html71
-rw-r--r--docs/tutorials/014/page05.html1
-rw-r--r--docs/tutorials/015/page03.html77
-rw-r--r--docs/tutorials/015/page04.html5
-rw-r--r--docs/tutorials/015/page06.html44
-rw-r--r--docs/tutorials/015/page08.html67
-rw-r--r--docs/tutorials/015/page09.html6
-rw-r--r--docs/tutorials/015/page10.html102
-rw-r--r--docs/tutorials/015/page11.html224
-rw-r--r--docs/tutorials/015/page12.html78
-rw-r--r--docs/tutorials/015/page14.html65
-rw-r--r--docs/tutorials/015/page15.html25
-rw-r--r--docs/tutorials/015/page16.html80
-rw-r--r--docs/tutorials/015/page17.html6
-rw-r--r--docs/tutorials/015/page18.html41
-rw-r--r--docs/tutorials/015/page20.html25
-rw-r--r--docs/tutorials/016/page02.html286
-rw-r--r--docs/tutorials/016/page03.html2
-rw-r--r--docs/tutorials/016/page04.html3
-rw-r--r--docs/tutorials/016/page05.html3
-rw-r--r--docs/tutorials/017/page03.html66
-rw-r--r--docs/tutorials/018/page03.html78
-rw-r--r--docs/tutorials/018/page04.html257
-rw-r--r--docs/tutorials/018/page05.html18
-rw-r--r--docs/tutorials/019/page01.html3
-rw-r--r--docs/tutorials/019/page02.html207
-rw-r--r--docs/tutorials/019/page03.html101
-rw-r--r--docs/tutorials/019/page04.html160
-rw-r--r--docs/tutorials/019/page05.html69
-rw-r--r--docs/tutorials/019/page06.html1
-rw-r--r--docs/tutorials/020/page02.html4
-rw-r--r--docs/tutorials/020/page03.html3
-rw-r--r--docs/tutorials/020/page04.html4
-rw-r--r--docs/tutorials/020/page05.html19
-rw-r--r--docs/tutorials/021/page02.html246
-rw-r--r--docs/tutorials/021/page03.html184
-rw-r--r--docs/tutorials/021/page04.html63
-rw-r--r--docs/tutorials/021/page05.html53
-rw-r--r--docs/tutorials/Makefile2
55 files changed, 2124 insertions, 2100 deletions
diff --git a/docs/tutorials/001/page01.html b/docs/tutorials/001/page01.html
index e3e0a6dc714..3155a0b9c18 100644
--- a/docs/tutorials/001/page01.html
+++ b/docs/tutorials/001/page01.html
@@ -1,22 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<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]">
+ <TITLE>ACE Tutorial 001</TITLE>
+ <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]">
<META NAME="Author" CONTENT="James CE Johnson">
<META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 001</TITLE>
</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
+<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff">
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
+<CENTER><P><B><FONT SIZE=+2>ACE&nbsp;Tutorial 001<BR>
+A Beginners Guide to Using the ACE&nbsp;Toolkit</FONT></B></P></CENTER>
+<hr>
<P>The purpose of this tutorial is to show you how to create a very simple
server capable of handling multiple client connections. Unlike a &quot;traditional&quot;
server application, this one handles all requests in one process. Issues
@@ -101,5 +97,6 @@ If all of this is gibberish and makes you think that ACE is way to hard to
learn, don't worry. We'll go into all the details and explain as we go.
I only went into all of this so that it can kick around in the back of your
mind until you need it later.
+<P>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/001/page02.html b/docs/tutorials/001/page02.html
index e7b8dde396c..dff82baa375 100644
--- a/docs/tutorials/001/page02.html
+++ b/docs/tutorials/001/page02.html
@@ -1,21 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<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]">
+ <TITLE>ACE Tutorial 001</TITLE>
+ <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]">
<META NAME="Author" CONTENT="James CE Johnson">
<META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 001</TITLE>
</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER>
-
-<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER>
+<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff">
-<P>
-<HR WIDTH="100%">
+<CENTER><P><B><FONT SIZE=+2>ACE&nbsp;Tutorial 001<BR>
+A Beginners Guide to Using the ACE&nbsp;Toolkit</FONT></B></P></CENTER>
+<hr>
<P>From here, we to move on to the main program loop. In a way, we're
starting at the final product when we do this, but it is a very simple
piece of code and a good place to start.
@@ -69,7 +66,7 @@ The READ_MASK is also defined in the ACE_Event_Handler class. It's
used to inform the Reactor that you want to register an event handler
to "read" data from an established connection.
</UL>
-<HR WIDTH="100%">
+<hr>
<PRE>
<font color=red>// $Id$</font>
@@ -176,5 +173,6 @@ Enter an infinite loop to let the reactor handle the events</LI>
On the next page, we will take a look at the acceptor and how it responds
to new connection requests.
+<P>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/001/page03.html b/docs/tutorials/001/page03.html
index 280b2aaec4c..5f45ca0826f 100644
--- a/docs/tutorials/001/page03.html
+++ b/docs/tutorials/001/page03.html
@@ -1,21 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<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]">
+ <TITLE>ACE Tutorial 001</TITLE>
+ <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]">
<META NAME="Author" CONTENT="James CE Johnson">
<META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 001</TITLE>
</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
+<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff">
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER>
-<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER>
-
-
-<P>
-<HR WIDTH="100%">
+<CENTER><P><B><FONT SIZE=+2>ACE&nbsp;Tutorial 001<BR>
+A Beginners Guide to Using the ACE&nbsp;Toolkit</FONT></B></P></CENTER>
+<hr>
<P>Now we begin to look at the <A HREF="acceptor.h">acceptor</A> object.
<P>
@@ -189,8 +186,7 @@ protected:
<font color=blue>#endif</font> <font color=red>/* _CLIENT_ACCEPTOR_H */</font>
</PRE>
-<HR>
-
+<HR WIDTH="100%"></PRE>
It is important to notice here that we have done very little application-specifc
code in developing this object. In fact, if we take out the progress information,
the only app-specific code is when we create the new <I>Logging_Handler</I>
diff --git a/docs/tutorials/001/page04.html b/docs/tutorials/001/page04.html
index 1ed51dbac02..079947a3b3a 100644
--- a/docs/tutorials/001/page04.html
+++ b/docs/tutorials/001/page04.html
@@ -1,26 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<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]">
+ <TITLE>ACE Tutorial 001</TITLE>
+ <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]">
<META NAME="Author" CONTENT="James CE Johnson">
<META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 001</TITLE>
</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER>
+<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff">
-<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER>
+<CENTER><P><B><FONT SIZE=+2>ACE&nbsp;Tutorial 001<BR>
+A Beginners Guide to Using the ACE&nbsp;Toolkit</FONT></B></P></CENTER>
-<P>
-<HR WIDTH="100%">
-
+<hr>
<P>Now we begin to look at the <A HREF="logger.h">logger</A>
object.
<P>
-<HR WIDTH="100%">
+<HR>
<PRE>
<font color=red>// $Id$</font>
@@ -200,7 +197,9 @@ protected:
<font color=blue>#endif</font> <font color=red>/* _CLIENT_HANDLER_H */</font>
</PRE>
-<HR>
+<HR WIDTH="100%">
+
+<P>
The comments really should tell the story. The really
interesting stuff is in <i>handle_input()</i>. Everything
else is just housekeeping.
diff --git a/docs/tutorials/001/page05.html b/docs/tutorials/001/page05.html
index 53bb40efb18..8725e1f410f 100644
--- a/docs/tutorials/001/page05.html
+++ b/docs/tutorials/001/page05.html
@@ -1,21 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<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]">
+ <TITLE>ACE Tutorial 001</TITLE>
+ <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]">
<META NAME="Author" CONTENT="James CE Johnson">
<META NAME="Description" CONTENT="A first step towards using ACE productively">
- <TITLE>ACE Tutorial 001</TITLE>
</HEAD>
-<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F">
-
-<CENTER><B><FONT SIZE=+2>ACE Tutorial 001</FONT></B></CENTER>
+<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff">
-<CENTER><B><FONT SIZE=+2>A Beginners Guide to Using the ACE Toolkit</FONT></B></CENTER>
+<CENTER><P><B><FONT SIZE=+2>ACE&nbsp;Tutorial 001<BR>
+A Beginners Guide to Using the ACE&nbsp;Toolkit</FONT></B></P></CENTER>
-<P>
-<HR WIDTH="100%">
-
+<hr>
<P>This concludes the first tutorial on using ACE. We've learned how to
create a simple server without knowing very much about network programming.
diff --git a/docs/tutorials/002/page03.html b/docs/tutorials/002/page03.html
index f5af30830d0..e2243550505 100644
--- a/docs/tutorials/002/page03.html
+++ b/docs/tutorials/002/page03.html
@@ -21,7 +21,6 @@
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>LOGGING_HANDLER_H</font>
@@ -36,157 +35,157 @@
<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>"
<font color=blue>#include</font> "<font color=green>ace/Reactor.h</font>"
-<font color=red>/*
- Since we used the template to create the acceptor, we don't know if there is a
- way to get to the reactor it uses. We'll take the easy way out and grab the
- global pointer. (There is a way to get back to the acceptor's reactor that
- we'll see later on.)
- */</font>
+<font color=red>/* Since we used the template to create the acceptor, we don't know if
+ there is a way to get to the reactor it uses. We'll take the easy
+ way out and grab the global pointer. (There is a way to get back to
+ the acceptor's reactor that we'll see later on.) */</font>
extern ACE_Reactor * g_reactor;
-<font color=red>/*
- This time we're deriving from ACE_Svc_Handler instead of ACE_Event_Handler.
- The big reason for this is because it already knows how to contain a SOCK_Stream
- and provides all of the method calls needed by the reactor. The second template
- parameter is for some advanced stuff we'll do with later servers. For now, just
- use it as is...
- */</font>
-class Logging_Handler : public ACE_Svc_Handler &lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH >
+<font color=red>/* This time we're deriving from ACE_Svc_Handler instead of
+ ACE_Event_Handler. The big reason for this is because it already
+ knows how to contain a SOCK_Stream and provides all of the method
+ calls needed by the reactor. The second template parameter is for
+ some advanced stuff we'll do with later servers. For now, just use
+ it as is... */</font>
+class Logging_Handler : public ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
-
public:
- <font color=red>/*
- The Acceptor&lt;> template will open() us when there is a new client connection.
- */</font>
+ <font color=red>/* The Acceptor&lt;> template will open() us when there is a new client
+ connection. */</font>
virtual int open (void *)
{
ACE_INET_Addr addr;
- <font color=red>/*
- Ask the peer() (held in our baseclass) to tell us the address of the cient
- which has connected. There may be valid reasons for this to fail where we
- wouldn't want to drop the connection but I can't think of one.
- */</font>
+ <font color=red>/* Ask the peer() (held in our baseclass) to tell us the address
+ of the cient which has connected. There may be valid reasons
+ for this to fail where we wouldn't want to drop the connection
+ but I can't think of one. */</font>
if (this->peer ().get_remote_addr (addr) == -1)
return -1;
- <font color=red>/*
- The Acceptor&lt;> won't register us with it's reactor, so we have to do so
- ourselves. This is where we have to grab that global pointer. Notice
- that we again use the READ_MASK so that handle_input() will be called
- when the client does something.
- */</font>
- if (g_reactor->register_handler (this, <font color=#008888>ACE_Event_Handler::READ_MASK</font>) == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) can't register with reactor\n</font>"), -1);
-
- <font color=red>/*
- Here's another new treat. We schedule a timer event. This particular one
- will fire in two seconds and then every three seconds after that. It doesn't
- serve any useful purpose in our application other than to show you how it
- is done.
- */</font>
- else if (g_reactor->schedule_timer (this, 0, ACE_Time_Value (2), ACE_Time_Value (3)) == -1)
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>can'(%P|%t) t register with reactor\n</font>"), -1);
-
- ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) connected with %s\n</font>", addr.get_host_name() ));
+ <font color=red>/* The Acceptor&lt;> won't register us with it's reactor, so we have
+ to do so ourselves. This is where we have to grab that global
+ pointer. Notice that we again use the READ_MASK so that
+ handle_input() will be called when the client does something. */</font>
+ if (g_reactor->register_handler (this,
+ <font color=#008888>ACE_Event_Handler::READ_MASK</font>) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) can't register with reactor\n</font>"),
+ -1);
+
+ <font color=red>/* Here's another new treat. We schedule a timer event. This
+ particular one will fire in two seconds and then every three
+ seconds after that. It doesn't serve any useful purpose in our
+ application other than to show you how it is done. */</font>
+ else if (g_reactor->schedule_timer (this,
+ 0,
+ ACE_Time_Value (2),
+ ACE_Time_Value (3)) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>can'(%P|%t) t register with reactor\n</font>"),
+ -1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "<font color=green>(%P|%t) connected with %s\n</font>",
+ addr.get_host_name ()));
return 0;
}
- <font color=red>/*
- This is a matter of style & maybe taste. Instead of putting all of this stuff
- into a destructor, we put it here and request that everyone call destroy()
- instead of 'delete'.
- */</font>
+ <font color=red>/* This is a matter of style & maybe taste. Instead of putting all
+ of this stuff into a destructor, we put it here and request that
+ everyone call destroy() instead of 'delete'. */</font>
virtual void destroy (void)
{
- <font color=red>/*
- Remove ourselves from the reactor
- */</font>
- g_reactor->remove_handler(this,<font color=#008888>ACE_Event_Handler::READ_MASK</font>|ACE_Event_Handler::DONT_CALL);
+ <font color=red>/* Remove ourselves from the reactor */</font>
+ g_reactor->remove_handler
+ (this,
+ <font color=#008888>ACE_Event_Handler::READ_MASK</font> | ACE_Event_Handler::DONT_CALL);
- <font color=red>/*
- Cancel that timer we scheduled in open()
- */</font>
+ <font color=red>/* Cancel that timer we scheduled in open() */</font>
g_reactor->cancel_timer (this);
- <font color=red>/*
- Shut down the connection to the client.
- */</font>
+ <font color=red>/* Shut down the connection to the client. */</font>
this->peer ().close ();
- <font color=red>/*
- Free our memory.
- */</font>
+ <font color=red>/* Free our memory. */</font>
delete this;
}
- <font color=red>/*
- If somebody doesn't like us, they will close() us. Actually, if our open() method
- returns -1, the Acceptor&lt;> will invoke close() on us for cleanup.
- */</font>
- virtual int close (u_long _flags = 0)
+ <font color=red>/* If somebody doesn't like us, they will close() us. Actually, if
+ our open() method returns -1, the Acceptor&lt;> will invoke close()
+ on us for cleanup. */</font>
+ virtual int close (u_long flags = 0)
{
- <font color=red>/*
- The ACE_Svc_Handler baseclass requires the _flags parameter. We don't
- use it here though, so we mark it as UNUSED. You can accomplish the
- same thing with a signature like handle_input's below.
- */</font>
- ACE_UNUSED_ARG(_flags);
+ <font color=red>/* The ACE_Svc_Handler baseclass requires the &lt;flags> parameter.
+ We don't use it here though, so we mark it as UNUSED. You can
+ accomplish the same thing with a signature like handle_input's
+ below. */</font>
+ ACE_UNUSED_ARG (flags);
<font color=red>/*
Clean up and go away.
- */</font>
+ */</font>
this->destroy ();
return 0;
}
protected:
- <font color=red>/*
- Respond to input just like Tutorial 1.
- */</font>
+ <font color=red>/* Respond to input just like Tutorial 1. */</font>
virtual int handle_input (ACE_HANDLE)
{
char buf[128];
- memset (buf, 0, sizeof (buf));
-
- switch (this->peer ().recv (buf, sizeof buf))
- {
- case -1:
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) %p bad read\n</font>", "<font color=green>client logger</font>"), -1);
- case 0:
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) closing log daemon (fd = %d)\n</font>", this->get_handle ()), -1);
- default:
- ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) from client: %s</font>", buf));
- }
+ <font color=#008888>ACE_OS::memset</font> (buf, 0, sizeof (buf));
+
+ switch (this->peer ().recv (buf,
+ sizeof buf))
+ {
+ case -1:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) %p bad read\n</font>",
+ "<font color=green>client logger</font>"),
+ -1);
+ case 0:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) closing log daemon (fd = %d)\n</font>",
+ this->get_handle ()),
+ -1);
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "<font color=green>(%P|%t) from client: %s</font>",
+ buf));
+ }
return 0;
}
- <font color=red>/*
- When the timer expires, handle_timeout() will be called. The 'arg' is the value passed
- after 'this' in the schedule_timer() call. You can pass in anything there that you can
- cast to a void*.
- */</font>
- virtual int handle_timeout (const ACE_Time_Value & tv, const void *arg)
+ <font color=red>/* When the timer expires, handle_timeout() will be called. The
+ 'arg' is the value passed after 'this' in the schedule_timer()
+ call. You can pass in anything there that you can cast to a
+ void*. */</font>
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg)
{
- ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) handling timeout from this = %u\n</font>", this));
+ ACE_DEBUG ((LM_DEBUG,
+ "<font color=green>(%P|%t) handling timeout from this = %u\n</font>",
+ this));
return 0;
}
<font color=red>/*
Clean ourselves up when handle_input() (or handle_timer()) returns -1
- */</font>
- virtual int handle_close(ACE_HANDLE, ACE_Reactor_Mask _mask)
+ */</font>
+ virtual int handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask)
{
- this->destroy();
+ this->destroy ();
return 0;
}
};
-<font color=blue>#endif</font> <font color=red>// LOGGING_HANDLER_H</font>
+<font color=blue>#endif</font> <font color=red>/* LOGGING_HANDLER_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/005/page03.html b/docs/tutorials/005/page03.html
index 74f9624864f..cbc91cb4600 100644
--- a/docs/tutorials/005/page03.html
+++ b/docs/tutorials/005/page03.html
@@ -30,18 +30,15 @@ with an object type to instantiate when a new connection arrives.
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CLIENT_ACCEPTOR_H</font>
<font color=blue>#define</font> <font color=purple>CLIENT_ACCEPTOR_H</font>
-<font color=red>/*
- The ACE_Acceptor&lt;> template lives in the ace/Acceptor.h header file. You'll
- find a very consitent naming convention between the ACE objects and the
- headers where they can be found. In general, the ACE object ACE_Foobar will
- be found in ace/Foobar.h.
- */</font>
+<font color=red>/* The ACE_Acceptor&lt;> template lives in the ace/Acceptor.h header
+ file. You'll find a very consitent naming convention between the
+ ACE objects and the headers where they can be found. In general,
+ the ACE object ACE_Foobar will be found in ace/Foobar.h. */</font>
<font color=blue>#include</font> "<font color=green>ace/Acceptor.h</font>"
@@ -49,30 +46,26 @@ with an object type to instantiate when a new connection arrives.
# pragma once
<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>
-<font color=red>/*
- Since we want to work with sockets, we'll need a SOCK_Acceptor to allow the
- clients to connect to us.
- */</font>
+<font color=red>/* Since we want to work with sockets, we'll need a SOCK_Acceptor to
+ allow the clients to connect to us. */</font>
<font color=blue>#include</font> "<font color=green>ace/SOCK_Acceptor.h</font>"
-<font color=red>/*
- The Client_Handler object we develop will be used to handle clients once
- they're connected. The ACE_Acceptor&lt;> template's first parameter requires
- such an object. In some cases, you can get by with just a forward
- declaration on the class, in others you have to have the whole thing.
- */</font>
+<font color=red>/* The Client_Handler object we develop will be used to handle clients
+ once they're connected. The ACE_Acceptor&lt;> template's first
+ parameter requires such an object. In some cases, you can get by
+ with just a forward declaration on the class, in others you have to
+ have the whole thing. */</font>
<font color=blue>#include</font> "<font color=green>client_handler.h</font>"
-<font color=red>/*
- Parameterize the ACE_Acceptor&lt;> such that it will listen for socket
- connection attempts and create Client_Handler objects when they happen. In
- Tutorial 001, we wrote the basic acceptor logic on our own before we
- realized that ACE_Acceptor&lt;> was available. You'll get spoiled using the
- ACE templates because they take away a lot of the tedious details!
- */</font>
-typedef ACE_Acceptor &lt; Client_Handler, ACE_SOCK_ACCEPTOR > Client_Acceptor;
+<font color=red>/* Parameterize the ACE_Acceptor&lt;> such that it will listen for socket
+ connection attempts and create Client_Handler objects when they
+ happen. In Tutorial 001, we wrote the basic acceptor logic on our
+ own before we realized that ACE_Acceptor&lt;> was available. You'll
+ get spoiled using the ACE templates because they take away a lot of
+ the tedious details! */</font>
+typedef ACE_Acceptor &lt;Client_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor;
-<font color=blue>#endif</font> <font color=red>// CLIENT_ACCEPTOR_H</font>
+<font color=blue>#endif</font> <font color=red>/* CLIENT_ACCEPTOR_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/005/page04.html b/docs/tutorials/005/page04.html
index 4856284e895..a89deb91336 100644
--- a/docs/tutorials/005/page04.html
+++ b/docs/tutorials/005/page04.html
@@ -28,22 +28,21 @@ the definition where all of the real work of the application takes place.
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CLIENT_HANDLER_H</font>
<font color=blue>#define</font> <font color=purple>CLIENT_HANDLER_H</font>
-<font color=red>/*
- Our client handler must exist somewhere in the ACE_Event_Handler object
- hierarchy. This is a requirement of the ACE_Reactor because it maintains
- ACE_Event_Handler pointers for each registered event handler. You could
- derive our Client_Handler directly from ACE_Event_Handler but you still have
- to have an ACE_SOCK_Stream for the actual connection. With a direct
- derivative of ACE_Event_Handler, you'll have to contain and maintain an
- ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a
- derivative of ACE_Event_Handler) some of those details are handled for you.
-
+<font color=red>/* Our client handler must exist somewhere in the ACE_Event_Handler
+ object hierarchy. This is a requirement of the ACE_Reactor because
+ it maintains ACE_Event_Handler pointers for each registered event
+ handler. You could derive our Client_Handler directly from
+ ACE_Event_Handler but you still have to have an ACE_SOCK_Stream for
+ the actual connection. With a direct derivative of
+ ACE_Event_Handler, you'll have to contain and maintain an
+ ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is
+ a derivative of ACE_Event_Handler) some of those details are
+ handled for you.
*/</font>
<font color=blue>#include</font> "<font color=green>ace/Svc_Handler.h</font>"
@@ -54,91 +53,82 @@ the definition where all of the real work of the application takes place.
<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>"
-<font color=red>/*
- Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task&lt;>
- interface as well. That's what the ACE_NULL_SYNCH parameter below is all
- about. That's beyond our scope here but we'll come back to it in the next
- tutorial when we start looking at concurrency options.
- */</font>
-class Client_Handler : public ACE_Svc_Handler &lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH >
+<font color=red>/* Another feature of ACE_Svc_Handler is it's ability to present the
+ ACE_Task&lt;> interface as well. That's what the ACE_NULL_SYNCH
+ parameter below is all about. That's beyond our scope here but
+ we'll come back to it in the next tutorial when we start looking at
+ concurrency options. */</font>
+class Client_Handler : public ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
public:
-
<font color=red>// Constructor...</font>
Client_Handler (void);
- <font color=red>/*
- The destroy() method is our preferred method of destruction. We could
- have overloaded the delete operator but that is neither easy nor
- intuitive (at least to me). Instead, we provide a new method of
- destruction and we make our destructor protected so that only ourselves,
- our derivatives and our friends can delete us. It's a nice
- compromise.
- */</font>
+ <font color=red>/* The destroy() method is our preferred method of destruction. We
+ could have overloaded the delete operator but that is neither easy
+ nor intuitive (at least to me). Instead, we provide a new method
+ of destruction and we make our destructor protected so that only
+ ourselves, our derivatives and our friends can delete us. It's a
+ nice compromise. */</font>
void destroy (void);
- <font color=red>/*
- Most ACE objects have an open() method. That's how you make them ready
- to do work. ACE_Event_Handler has a virtual open() method which allows us
- to create an override. ACE_Acceptor&lt;> will invoke this method after
- creating a new Client_Handler when a client connects. Notice that the
- parameter to open() is a void*. It just so happens that the pointer
- points to the acceptor which created us. You would like for the parameter
- to be an ACE_Acceptor&lt;>* but since ACE_Event_Handler is generic, that
- would tie it too closely to the ACE_Acceptor&lt;> set of objects. In our
- definition of open() you'll see how we get around that.
- */</font>
- int open (void *_acceptor);
-
- <font color=red>/*
- 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
- clean itself up. Since an event handler can be registered for more than
- one type of callback, the callback mask is provided to inform
- handle_close() exactly which method failed. That way, you don't have to
- maintain state information between your handle_* method calls. The _handle
- parameter is explained below...
- As a side-effect, the reactor will also invoke remove_handler()
- for the object on the mask that caused the -1 return. This means
- that we don't have to do that ourselves!
- */</font>
- int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask);
+ <font color=red>/* Most ACE objects have an open() method. That's how you make them
+ ready to do work. ACE_Event_Handler has a virtual open() method
+ which allows us to create an override. ACE_Acceptor&lt;> will invoke
+ this method after creating a new Client_Handler when a client
+ connects. Notice that the parameter to open() is a void*. It just
+ so happens that the pointer points to the acceptor which created
+ us. You would like for the parameter to be an ACE_Acceptor&lt;>* but
+ since ACE_Event_Handler is generic, that would tie it too closely
+ to the ACE_Acceptor&lt;> set of objects. In our definition of open()
+ you'll see how we get around that. */</font>
+ int open (void *acceptor);
+
+ <font color=red>/* 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 clean itself
+ up. Since an event handler can be registered for more than one
+ type of callback, the callback mask is provided to inform
+ handle_close() exactly which method failed. That way, you don't
+ have to maintain state information between your handle_* method
+ calls. The &lt;handle> parameter is explained below... As a
+ side-effect, the reactor will also invoke remove_handler() for the
+ object on the mask that caused the -1 return. This means that we
+ don't have to do that ourselves! */</font>
+ int handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask);
protected:
- <font color=red>/*
- When we register with the reactor, we're going to tell it that we want to
- be notified of READ events. When the reactor sees that there is read
- activity for us, our handle_input() will be invoked. The _handle
- provided is the handle (file descriptor in Unix) of the actual connection
- causing the activity. Since we're derived from ACE_Svc_Handler&lt;> and it
- maintains its own peer (ACE_SOCK_Stream) object, this is redundant for
- us. However, if we had been derived directly from ACE_Event_Handler, we
- may have chosen not to contain the peer. In that case, the _handle
- would be important to us for reading the client's data.
- */</font>
- int handle_input (ACE_HANDLE _handle);
-
- <font color=red>/*
- This has nothing at all to do with ACE. I've added this here as a worker
- function which I will call from handle_input(). That allows me to
- introduce concurrency in later tutorials with no changes to the worker
- function. You can think of process() as application-level code and
- everything else as application-framework code.
- */</font>
- int process (char *_rdbuf, int _rdbuf_len);
-
- <font color=red>/*
- We don't really do anything in our destructor but we've declared it to be
- protected to prevent casual deletion of this object. As I said above, I
- really would prefer that everyone goes through the destroy() method to get
- rid of us.
- */</font>
- ~Client_Handler (void);
+ <font color=red>/* When we register with the reactor, we're going to tell it that we
+ want to be notified of READ events. When the reactor sees that
+ there is read activity for us, our handle_input() will be
+ invoked. The _handle provided is the handle (file descriptor in
+ Unix) of the actual connection causing the activity. Since we're
+ derived from ACE_Svc_Handler&lt;> and it maintains its own peer
+ (ACE_SOCK_Stream) object, this is redundant for us. However, if
+ we had been derived directly from ACE_Event_Handler, we may have
+ chosen not to contain the peer. In that case, the &lt;handle> would
+ be important to us for reading the client's data. */</font>
+ int handle_input (ACE_HANDLE handle);
+
+ <font color=red>/* This has nothing at all to do with ACE. I've added this here as
+ a worker function which I will call from handle_input(). That
+ allows me to introduce concurrency in later tutorials with no
+ changes to the worker function. You can think of process() as
+ application-level code and everything else as
+ application-framework code. */</font>
+ int process (char *rdbuf, int rdbuf_len);
+
+ <font color=red>/* We don't really do anything in our destructor but we've declared
+ it to be protected to prevent casual deletion of this object. As
+ I said above, I really would prefer that everyone goes through the
+ destroy() method to get rid of us. */</font>
+ ~Client_Handler (void);
};
-<font color=blue>#endif</font> <font color=red>// CLIENT_HANDLER_H</font>
+<font color=blue>#endif</font> <font color=red>/* CLIENT_HANDLER_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/006/page01.html b/docs/tutorials/006/page01.html
index 82864098ccc..31380d02b6d 100644
--- a/docs/tutorials/006/page01.html
+++ b/docs/tutorials/006/page01.html
@@ -49,7 +49,7 @@ called per thread for the thread-per-connection server.
<p>
Note that here all the Client_Handler objects aren't registered with the
reactor. The Reactor is only used to accept client connections. Once a
-thread has been dedicated per connection, the Client Handler object
+thread has been deicated per connection, the Client Handler object
reponsible for that client connection now takes up the job of the
reactor and handles future events.
<p>
diff --git a/docs/tutorials/006/page03.html b/docs/tutorials/006/page03.html
index cf164c5b4d8..08e5b70c78b 100644
--- a/docs/tutorials/006/page03.html
+++ b/docs/tutorials/006/page03.html
@@ -26,20 +26,15 @@ to the Tutorial 5 version of this file.
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CLIENT_ACCEPTOR_H</font>
<font color=blue>#define</font> <font color=purple>CLIENT_ACCEPTOR_H</font>
-<font color=red>/*
- The ACE_Acceptor&lt;> template lives in the ace/Acceptor.h header file. You'll
- find a very consistent naming convention between the ACE objects and the
- headers where they can be found. In general, the ACE object ACE_Foobar will
-
-
- be found in ace/Foobar.h.
- */</font>
+<font color=red>/* The ACE_Acceptor&lt;> template lives in the ace/Acceptor.h header
+ file. You'll find a very consistent naming convention between the
+ ACE objects and the headers where they can be found. In general,
+ the ACE object ACE_Foobar will be found in ace/Foobar.h. */</font>
<font color=blue>#include</font> "<font color=green>ace/Acceptor.h</font>"
@@ -47,70 +42,64 @@ to the Tutorial 5 version of this file.
# pragma once
<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>
-<font color=red>/*
- Since we want to work with sockets, we'll need a SOCK_Acceptor to allow the
- clients to connect to us.
- */</font>
+<font color=red>/* Since we want to work with sockets, we'll need a SOCK_Acceptor to
+ allow the clients to connect to us. */</font>
<font color=blue>#include</font> "<font color=green>ace/SOCK_Acceptor.h</font>"
-<font color=red>/*
- The Client_Handler object we develop will be used to handle clients once
- they're connected. The ACE_Acceptor&lt;> template's first parameter requires
- such an object. In some cases, you can get by with just a forward
- declaration on the class, in others you have to have the whole thing.
- */</font>
+<font color=red>/* The Client_Handler object we develop will be used to handle clients
+ once they're connected. The ACE_Acceptor&lt;> template's first
+ parameter requires such an object. In some cases, you can get by
+ with just a forward declaration on the class, in others you have to
+ have the whole thing. */</font>
<font color=blue>#include</font> "<font color=green>client_handler.h</font>"
-<font color=red>/*
- Parameterize the ACE_Acceptor&lt;> such that it will listen for socket
- connection attempts and create Client_Handler objects when they happen. In
- Tutorial 001, we wrote the basic acceptor logic on our own before we
- realized that ACE_Acceptor&lt;> was available. You'll get spoiled using the
- ACE templates because they take away a lot of the tedious details!
- */</font>
-typedef ACE_Acceptor &lt; Client_Handler, ACE_SOCK_ACCEPTOR > Client_Acceptor_Base;
-
-<font color=red>/*
- Here, we use the parameterized ACE_Acceptor&lt;> as a baseclass for our customized
- Client_Acceptor object. I've done this so that we can provide it with our choice
- of concurrency strategies when the object is created. Each Client_Handler it
- creates will use this information to determine how to act. If we were going
- to create a system that was always thread-per-connection, we would not have
- bothered to extend Client_Acceptor.
- */</font>
+<font color=red>/* Parameterize the ACE_Acceptor&lt;> such that it will listen for socket
+ connection attempts and create Client_Handler objects when they
+ happen. In Tutorial 001, we wrote the basic acceptor logic on our
+ own before we realized that ACE_Acceptor&lt;> was available. You'll
+ get spoiled using the ACE templates because they take away a lot of
+ the tedious details! */</font>
+typedef ACE_Acceptor &lt;Client_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor_Base;
+
+<font color=red>/* Here, we use the parameterized ACE_Acceptor&lt;> as a baseclass for
+ our customized Client_Acceptor object. I've done this so that we
+ can provide it with our choice of concurrency strategies when the
+ object is created. Each Client_Handler it creates will use this
+ information to determine how to act. If we were going to create a
+ system that was always thread-per-connection, we would not have
+ bothered to extend Client_Acceptor. */</font>
class Client_Acceptor : public Client_Acceptor_Base
{
public:
- <font color=red>/*
- This is always a good idea. If nothing else, it makes your code more
- orthogonal no matter what baseclasses your objects have.
- */</font>
- typedef Client_Acceptor_Base inherited;
-
- <font color=red>/*
- Construct the object with the concurrency strategy. Since this tutorial
- is focused on thread-per-connection, we make that the default. We could
- have chosen to omitt the default and populate it in main() instead.
- */</font>
- Client_Acceptor( int _thread_per_connection = 1 )
- : thread_per_connection_(_thread_per_connection)
- {
- }
-
- <font color=red>/*
- Return the value of our strategy flag. This is used by the Client_Handler
- to decide how to act. If 'true' then the handler will behave in a
- thread-per-connection manner.
- */</font>
- int thread_per_connection(void)
- { return this->thread_per_connection_; }
+ <font color=red>/*
+ This is always a good idea. If nothing else, it makes your code more
+ orthogonal no matter what baseclasses your objects have.
+ */</font>
+ typedef Client_Acceptor_Base inherited;
+
+ <font color=red>/*
+ Construct the object with the concurrency strategy. Since this tutorial
+ is focused on thread-per-connection, we make that the default. We could
+ have chosen to omitt the default and populate it in main() instead.
+ */</font>
+ Client_Acceptor (int thread_per_connection = 1)
+ : thread_per_connection_ (thread_per_connection)
+ {
+ }
+
+ <font color=red>/* Return the value of our strategy flag. This is used by the
+ Client_Handler to decide how to act. If 'true' then the handler
+ will behave in a thread-per-connection manner. */</font>
+ int thread_per_connection (void)
+ {
+ return this->thread_per_connection_;
+ }
protected:
- int thread_per_connection_;
-
+ int thread_per_connection_;
};
-<font color=blue>#endif</font> <font color=red>// CLIENT_ACCEPTOR_H</font>
+<font color=blue>#endif</font> <font color=red>/* CLIENT_ACCEPTOR_H */</font>
</PRE>
<HR WIDTH="100%">
diff --git a/docs/tutorials/006/page04.html b/docs/tutorials/006/page04.html
index 130c264cec7..a580702f0cd 100644
--- a/docs/tutorials/006/page04.html
+++ b/docs/tutorials/006/page04.html
@@ -23,21 +23,21 @@ exist.
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CLIENT_HANDLER_H</font>
<font color=blue>#define</font> <font color=purple>CLIENT_HANDLER_H</font>
-<font color=red>/*
- Our client handler must exist somewhere in the ACE_Event_Handler object
- hierarchy. This is a requirement of the ACE_Reactor because it maintains
- ACE_Event_Handler pointers for each registered event handler. You could
- derive our Client_Handler directly from ACE_Event_Handler but you still have
- to have an ACE_SOCK_Stream for the actually connection. With a direct
- derivative of ACE_Event_Handler, you'll have to contain and maintain an
- ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a
- derivative of ACE_Event_Handler) some of those details are handled for you.
+<font color=red>/* Our client handler must exist somewhere in the ACE_Event_Handler
+ object hierarchy. This is a requirement of the ACE_Reactor because
+ it maintains ACE_Event_Handler pointers for each registered event
+ handler. You could derive our Client_Handler directly from
+ ACE_Event_Handler but you still have to have an ACE_SOCK_Stream for
+ the actually connection. With a direct derivative of
+ ACE_Event_Handler, you'll have to contain and maintain an
+ ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is
+ a derivative of ACE_Event_Handler) some of those details are
+ handled for you.
*/</font>
@@ -49,110 +49,98 @@ exist.
<font color=blue>#include</font> "<font color=green>ace/SOCK_Stream.h</font>"
-<font color=red>/*
- Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task&lt;>
- interface as well. That's what the ACE_NULL_SYNCH parameter below is all
- about. If our Client_Acceptor has chosen thread-per-connection then our
- open() method will activate us into a thread. At that point, our svc()
- method will execute. We still don't take advantage of the things
- ACE_NULL_SYNCH exists for but stick around for Tutorial 7 and pay special
- attention to the Thread_Pool object there for an explanation.
- */</font>
-class Client_Handler : public ACE_Svc_Handler &lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH >
+<font color=red>/* Another feature of ACE_Svc_Handler is it's ability to present the
+ ACE_Task&lt;> interface as well. That's what the ACE_NULL_SYNCH
+ parameter below is all about. If our Client_Acceptor has chosen
+ thread-per-connection then our open() method will activate us into
+ a thread. At that point, our svc() method will execute. We still
+ don't take advantage of the things ACE_NULL_SYNCH exists for but
+ stick around for Tutorial 7 and pay special attention to the
+ Thread_Pool object there for an explanation. */</font>
+class Client_Handler : public ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
public:
- typedef ACE_Svc_Handler &lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited;
+ typedef ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH> inherited;
<font color=red>// Constructor...</font>
Client_Handler (void);
- <font color=red>/*
- The destroy() method is our preferred method of destruction. We could
- have overloaded the delete operator but that is neither easy nor
- intuitive (at least to me). Instead, we provide a new method of
- destruction and we make our destructor protected so that only ourselves,
- our derivatives and our friends can delete us. It's a nice
- compromise.
- */</font>
+ <font color=red>/* The destroy() method is our preferred method of destruction. We
+ could have overloaded the delete operator but that is neither easy
+ nor intuitive (at least to me). Instead, we provide a new method
+ of destruction and we make our destructor protected so that only
+ ourselves, our derivatives and our friends can delete us. It's a
+ nice compromise. */</font>
void destroy (void);
- <font color=red>/*
- Most ACE objects have an open() method. That's how you make them ready
- to do work. ACE_Event_Handler has a virtual open() method which allows us
- to create this overrride. ACE_Acceptor&lt;> will invoke this method after
- creating a new Client_Handler when a client connects. Notice that the
- parameter to open() is a void*. It just so happens that the pointer
- points to the acceptor which created us. You would like for the parameter
- to be an ACE_Acceptor&lt;>* but since ACE_Event_Handler is generic, that
- would tie it too closely to the ACE_Acceptor&lt;> set of objects. In our
- definition of open() you'll see how we get around that.
- */</font>
- int open (void *_acceptor);
-
- <font color=red>/*
- When an ACE_Task&lt;> 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.
- */</font>
- int close(u_long flags = 0);
-
- <font color=red>/*
- 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
- clean itself up. Since an event handler can be registered for more than
- one type of callback, the callback mask is provided to inform
- handle_close() exactly which method failed. That way, you don't have to
- maintain state information between your handle_* method calls. The _handle
- parameter is explained below...
- As a side-effect, the reactor will also invoke remove_handler()
- for the object on the mask that caused the -1 return. This means
- that we don't have to do that ourselves!
- */</font>
- virtual int handle_close (ACE_HANDLE _handle = ACE_INVALID_HANDLE,
- ACE_Reactor_Mask _mask = <font color=#008888>ACE_Event_Handler::ALL_EVENTS_MASK</font> );
+ <font color=red>/* Most ACE objects have an open() method. That's how you make them
+ ready to do work. ACE_Event_Handler has a virtual open() method
+ which allows us to create this overrride. ACE_Acceptor&lt;> will
+ invoke this method after creating a new Client_Handler when a
+ client connects. Notice that the parameter to open() is a void*.
+ It just so happens that the pointer points to the acceptor which
+ created us. You would like for the parameter to be an
+ ACE_Acceptor&lt;>* but since ACE_Event_Handler is generic, that would
+ tie it too closely to the ACE_Acceptor&lt;> set of objects. In our
+ definition of open() you'll see how we get around that. */</font>
+ int open (void *acceptor);
+
+ <font color=red>/* When an ACE_Task&lt;> 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. */</font>
+ int close (u_long flags = 0);
+
+ <font color=red>/* 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 clean itself
+ up. Since an event handler can be registered for more than one
+ type of callback, the callback mask is provided to inform
+ handle_close() exactly which method failed. That way, you don't
+ have to maintain state information between your handle_* method
+ calls. The &lt;handle> parameter is explained below... As a
+ side-effect, the reactor will also invoke remove_handler() for the
+ object on the mask that caused the -1 return. This means that we
+ don't have to do that ourselves! */</font>
+ virtual int handle_close (ACE_HANDLE handle = ACE_INVALID_HANDLE,
+ ACE_Reactor_Mask mask = <font color=#008888>ACE_Event_Handler::ALL_EVENTS_MASK</font> );
protected:
- <font color=red>/*
- If the Client_Acceptor which created us has chosen a thread-per-connection
- strategy then our open() method will activate us into a dedicate thread.
- The svc() method will then execute in that thread performing some of the
- functions we used to leave up to the reactor.
- */</font>
- int svc(void);
-
- <font color=red>/*
- When we register with the reactor, we're going to tell it that we want to
- be notified of READ events. When the reactor sees that there is read
- activity for us, our handle_input() will be invoked. The _handleg
- provided is the handle (file descriptor in Unix) of the actual connection
- causing the activity. Since we're derived from ACE_Svc_Handler&lt;> and it
- maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for
- us. However, if we had been derived directly from ACE_Event_Handler, we
- may have chosen not to contain the peer. In that case, the _handleg
- would be important to us for reading the client's data.
- */</font>
- int handle_input (ACE_HANDLE _handle);
-
- <font color=red>/*
- This has nothing at all to do with ACE. I've added this here as a worker
- function which I will call from handle_input(). As promised in Tutorial 5
- I will use this now to make it easier to switch between our two possible
- concurrency strategies.
- */</font>
- int process (char *_rdbuf, int _rdbuf_len);
-
- <font color=red>/*
- We don't really do anything in our destructor but we've declared it to be
- protected to prevent casual deletion of this object. As I said above, I
- really would prefer that everyone goes through the destroy() method to get
- rid of us.
- */</font>
- ~Client_Handler (void);
+ <font color=red>/* If the Client_Acceptor which created us has chosen a
+ thread-per-connection strategy then our open() method will
+ activate us into a dedicate thread. The svc() method will then
+ execute in that thread performing some of the functions we used to
+ leave up to the reactor. */</font>
+ int svc (void);
+
+ <font color=red>/* When we register with the reactor, we're going to tell it that we
+ want to be notified of READ events. When the reactor sees that
+ there is read activity for us, our handle_input() will be
+ invoked. The _handleg provided is the handle (file descriptor in
+ Unix) of the actual connection causing the activity. Since we're
+ derived from ACE_Svc_Handler&lt;> and it maintains it's own peer
+ (ACE_SOCK_Stream) object, this is redundant for us. However, if
+ we had been derived directly from ACE_Event_Handler, we may have
+ chosen not to contain the peer. In that case, the &lt;handle> would
+ be important to us for reading the client's data. */</font>
+ int handle_input (ACE_HANDLE handle);
+
+ <font color=red>/* This has nothing at all to do with ACE. I've added this here as
+ a worker function which I will call from handle_input(). As
+ promised in Tutorial 5 I will use this now to make it easier to
+ switch between our two possible concurrency strategies. */</font>
+ int process (char *rdbuf, int rdbuf_len);
+
+ <font color=red>/* We don't really do anything in our destructor but we've declared
+ it to be protected to prevent casual deletion of this object. As
+ I said above, I really would prefer that everyone goes through the
+ destroy() method to get rid of us. */</font>
+ ~Client_Handler (void);
};
-<font color=blue>#endif</font> <font color=red>// CLIENT_HANDLER_H</font>
+<font color=blue>#endif</font> <font color=red>/* CLIENT_HANDLER_H */</font>
</PRE>
<HR WIDTH="100%">
diff --git a/docs/tutorials/007/page01.html b/docs/tutorials/007/page01.html
index e2585c7b3de..a1cd7ceac79 100644
--- a/docs/tutorials/007/page01.html
+++ b/docs/tutorials/007/page01.html
@@ -77,5 +77,6 @@ which provides an OO approach to thread-creation and implementation.
ACE_Message_Queue which is discussed in depth in
<A HREF="../010/page01.html">Tutorial 10</A>. Feel free to read ahead
if you get lost in the message queue stuff.
-</font><P><HR WIDTH="100%">
+</font>
+<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/007/page03.html b/docs/tutorials/007/page03.html
index 20ccb581c13..2040717c810 100644
--- a/docs/tutorials/007/page03.html
+++ b/docs/tutorials/007/page03.html
@@ -18,18 +18,15 @@
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CLIENT_ACCEPTOR_H</font>
<font color=blue>#define</font> <font color=purple>CLIENT_ACCEPTOR_H</font>
-<font color=red>/*
- The ACE_Acceptor&lt;> template lives in the ace/Acceptor.h header file. You'll
- find a very consitent naming convention between the ACE objects and the
- headers where they can be found. In general, the ACE object ACE_Foobar will
- be found in ace/Foobar.h.
- */</font>
+<font color=red>/* The ACE_Acceptor&lt;> template lives in the ace/Acceptor.h header
+ file. You'll find a very consitent naming convention between the
+ ACE objects and the headers where they can be found. In general,
+ the ACE object ACE_Foobar will be found in ace/Foobar.h. */</font>
<font color=blue>#include</font> "<font color=green>ace/Acceptor.h</font>"
@@ -37,128 +34,115 @@
# pragma once
<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>
-<font color=red>/*
- Since we want to work with sockets, we'll need a SOCK_Acceptor to allow the
- clients to connect to us.
- */</font>
+<font color=red>/* Since we want to work with sockets, we'll need a SOCK_Acceptor to
+ allow the clients to connect to us. */</font>
<font color=blue>#include</font> "<font color=green>ace/SOCK_Acceptor.h</font>"
-<font color=red>/*
- The Client_Handler object we develop will be used to handle clients once
- they're connected. The ACE_Acceptor&lt;> template's first parameter requires
- such an object. In some cases, you can get by with just a forward
- declaration on the class, in others you have to have the whole thing.
- */</font>
+<font color=red>/* The Client_Handler object we develop will be used to handle clients
+ once they're connected. The ACE_Acceptor&lt;> template's first
+ parameter requires such an object. In some cases, you can get by
+ with just a forward declaration on the class, in others you have to
+ have the whole thing. */</font>
<font color=blue>#include</font> "<font color=green>client_handler.h</font>"
-<font color=red>/*
- Parameterize the ACE_Acceptor&lt;> such that it will listen for socket
- connection attempts and create Client_Handler objects when they happen. In
- Tutorial 001, we wrote the basic acceptor logic on our own before we
- realized that ACE_Acceptor&lt;> was available. You'll get spoiled using the
- ACE templates because they take away a lot of the tedious details!
- */</font>
-typedef ACE_Acceptor &lt; Client_Handler, ACE_SOCK_ACCEPTOR > Client_Acceptor_Base;
+<font color=red>/* Parameterize the ACE_Acceptor&lt;> such that it will listen for socket
+ connection attempts and create Client_Handler objects when they
+ happen. In Tutorial 001, we wrote the basic acceptor logic on our
+ own before we realized that ACE_Acceptor&lt;> was available. You'll
+ get spoiled using the ACE templates because they take away a lot of
+ the tedious details! */</font>
+typedef ACE_Acceptor &lt;Client_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor_Base;
<font color=blue>#include</font> "<font color=green>thread_pool.h</font>"
-<font color=red>/*
- This time we've added quite a bit more to our acceptor. In addition to
- providing a choice of concurrency strategies, we also maintain a Thread_Pool
- object in case that strategy is chosen. The object still isn't very complex
- but it's come a long way from the simple typedef we had in Tutorial 5.
-
- Why keep the thread pool as a member? If we go back to the inetd concept
- you'll recall that we need several acceptors to make that work. We may have
- a situation in which our different client types requre different resources.
- That is, we may need a large thread pool for some client types and a smaller
- one for others. We could share a pool but then the client types may have
- undesirable impact on one another.
-
- Just in case you do want to share a single thread pool, there is a constructor
- below that will let you do that.
- */</font>
+<font color=red>/* This time we've added quite a bit more to our acceptor. In
+ addition to providing a choice of concurrency strategies, we also
+ maintain a Thread_Pool object in case that strategy is chosen. The
+ object still isn't very complex but it's come a long way from the
+ simple typedef we had in Tutorial 5.
+
+ Why keep the thread pool as a member? If we go back to the inetd
+ concept you'll recall that we need several acceptors to make that
+ work. We may have a situation in which our different client types
+ requre different resources. That is, we may need a large thread
+ pool for some client types and a smaller one for others. We could
+ share a pool but then the client types may have undesirable impact
+ on one another.
+
+ Just in case you do want to share a single thread pool, there is a
+ constructor below that will let you do that. */</font>
class Client_Acceptor : public Client_Acceptor_Base
{
public:
- typedef Client_Acceptor_Base inherited;
-
- <font color=red>/*
- Now that we have more than two strategies, we need more than a boolean
- to tell us what we're using. A set of enums is a good choice because
- it allows us to use named values. Another option would be a set of
- static const integers.
- */</font>
- enum concurrency_t
- {
- single_threaded_,
- thread_per_connection_,
- thread_pool_
- };
-
- <font color=red>/*
- The default constructor allows the programmer to choose the concurrency
- strategy. Since we want to focus on thread-pool, that's what we'll use
- if nothing is specified.
- */</font>
- Client_Acceptor( int _concurrency = thread_pool_ );
-
- <font color=red>/*
- Another option is to construct the object with an existing thread pool.
- The concurrency strategy is pretty obvious at that point.
- */</font>
- Client_Acceptor( Thread_Pool & _thread_pool );
-
- <font color=red>/*
- Our destructor will take care of shutting down the thread-pool
- if applicable.
- */</font>
- ~Client_Acceptor( void );
-
- <font color=red>/*
- Open ourselves and register with the given reactor. The thread pool size
- can be specified here if you want to use that concurrency strategy.
- */</font>
- int open( const ACE_INET_Addr & _addr, ACE_Reactor * _reactor,
- int _pool_size = <font color=#008888>Thread_Pool::default_pool_size_</font> );
-
- <font color=red>/*
- Close ourselves and our thread pool if applicable
- */</font>
- int close(void);
-
- <font color=red>/*
- What is our concurrency strategy?
- */</font>
- int concurrency(void)
- { return this->concurrency_; }
-
- <font color=red>/*
- Give back a pointer to our thread pool. Our Client_Handler objects
- will need this so that their handle_input() methods can put themselves
- into the pool. Another alternative would be a globally accessible
- thread pool. ACE_Singleton&lt;> is a way to achieve that.
- */</font>
- Thread_Pool * thread_pool(void)
- { return & this->the_thread_pool_; }
-
- <font color=red>/*
- Since we can be constructed with a Thread_Pool reference, there are times
- when we need to know if the thread pool we're using is ours or if we're
- just borrowing it from somebody else.
- */</font>
- int thread_pool_is_private(void)
- { return &the_thread_pool_ == &private_thread_pool_; }
+ typedef Client_Acceptor_Base inherited;
+
+ <font color=red>/* Now that we have more than two strategies, we need more than a
+ boolean to tell us what we're using. A set of enums is a good
+ choice because it allows us to use named values. Another option
+ would be a set of static const integers. */</font>
+ enum concurrency_t
+ {
+ single_threaded_,
+ thread_per_connection_,
+ thread_pool_
+ };
+
+ <font color=red>/* The default constructor allows the programmer to choose the
+ concurrency strategy. Since we want to focus on thread-pool,
+ that's what we'll use if nothing is specified. */</font>
+ Client_Acceptor (int concurrency = thread_pool_);
+
+ <font color=red>/* Another option is to construct the object with an existing thread
+ pool. The concurrency strategy is pretty obvious at that point. */</font>
+ Client_Acceptor (Thread_Pool &thread_pool);
+
+ <font color=red>/* Our destructor will take care of shutting down the thread-pool if
+ applicable. */</font>
+ ~Client_Acceptor (void);
+
+ <font color=red>/* Open ourselves and register with the given reactor. The thread
+ pool size can be specified here if you want to use that
+ concurrency strategy. */</font>
+ int open (const ACE_INET_Addr &addr,
+ ACE_Reactor *reactor,
+ int pool_size = <font color=#008888>Thread_Pool::default_pool_size_</font>);
+
+ <font color=red>/* Close ourselves and our thread pool if applicable */</font>
+ int close (void);
+
+ <font color=red>/* What is our concurrency strategy? */</font>
+ int concurrency (void)
+ {
+ return this->concurrency_;
+ }
+
+ <font color=red>/* Give back a pointer to our thread pool. Our Client_Handler
+ objects will need this so that their handle_input() methods can
+ put themselves into the pool. Another alternative would be a
+ globally accessible thread pool. ACE_Singleton&lt;> is a way to
+ achieve that. */</font>
+ Thread_Pool *thread_pool (void)
+ {
+ return &this->the_thread_pool_;
+ }
+
+ <font color=red>/* Since we can be constructed with a Thread_Pool reference, there
+ are times when we need to know if the thread pool we're using is
+ ours or if we're just borrowing it from somebody else. */</font>
+ int thread_pool_is_private (void)
+ {
+ return &the_thread_pool_ == &private_thread_pool_;
+ }
protected:
- int concurrency_;
+ int concurrency_;
- Thread_Pool private_thread_pool_;
+ Thread_Pool private_thread_pool_;
- Thread_Pool & the_thread_pool_;
+ Thread_Pool &the_thread_pool_;
};
-<font color=blue>#endif</font> <font color=red>// CLIENT_ACCEPTOR_H</font>
+<font color=blue>#endif</font> <font color=red>/* CLIENT_ACCEPTOR_H */</font>
</PRE>
<HR WIDTH="100%">
diff --git a/docs/tutorials/007/page05.html b/docs/tutorials/007/page05.html
index f3b27749232..a416cb32505 100644
--- a/docs/tutorials/007/page05.html
+++ b/docs/tutorials/007/page05.html
@@ -19,22 +19,21 @@ is next.
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CLIENT_HANDLER_H</font>
<font color=blue>#define</font> <font color=purple>CLIENT_HANDLER_H</font>
-<font color=red>/*
- Our client handler must exist somewhere in the ACE_Event_Handler object
- hierarchy. This is a requirement of the ACE_Reactor because it maintains
- ACE_Event_Handler pointers for each registered event handler. You could
- derive our Client_Handler directly from ACE_Event_Handler but you still have
- to have an ACE_SOCK_Stream for the actually connection. With a direct
- derivative of ACE_Event_Handler, you'll have to contain and maintain an
- ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is a
- derivative of ACE_Event_Handler) some of those details are handled for you.
- */</font>
+<font color=red>/* Our client handler must exist somewhere in the ACE_Event_Handler
+ object hierarchy. This is a requirement of the ACE_Reactor because
+ it maintains ACE_Event_Handler pointers for each registered event
+ handler. You could derive our Client_Handler directly from
+ ACE_Event_Handler but you still have to have an ACE_SOCK_Stream for
+ the actually connection. With a direct derivative of
+ ACE_Event_Handler, you'll have to contain and maintain an
+ ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is
+ a derivative of ACE_Event_Handler) some of those details are
+ handled for you. */</font>
<font color=blue>#include</font> "<font color=green>ace/Svc_Handler.h</font>"
@@ -47,150 +46,135 @@ is next.
class Client_Acceptor;
class Thread_Pool;
-<font color=red>/*
- Another feature of ACE_Svc_Handler is it's ability to present the ACE_Task&lt;>
- interface as well. That's what the ACE_NULL_SYNCH parameter below is all
- about. That's beyond our scope here but we'll come back to it in the next
- tutorial when we start looking at concurrency options.
- */</font>
-class Client_Handler : public ACE_Svc_Handler &lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH >
+<font color=red>/* Another feature of ACE_Svc_Handler is it's ability to present the
+ ACE_Task&lt;> interface as well. That's what the ACE_NULL_SYNCH
+ parameter below is all about. That's beyond our scope here but
+ we'll come back to it in the next tutorial when we start looking at
+ concurrency options. */</font>
+class Client_Handler : public ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
public:
- typedef ACE_Svc_Handler &lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH > inherited;
+ typedef ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH> inherited;
<font color=red>// Constructor...</font>
Client_Handler (void);
- <font color=red>/*
- The destroy() method is our preferred method of destruction. We could
- have overloaded the delete operator but that is neither easy nor
- intuitive (at least to me). Instead, we provide a new method of
- destruction and we make our destructor protected so that only ourselves,
- our derivatives and our friends can delete us. It's a nice
- compromise.
- */</font>
+ <font color=red>/* The destroy() method is our preferred method of destruction. We
+ could have overloaded the delete operator but that is neither easy
+ nor intuitive (at least to me). Instead, we provide a new method
+ of destruction and we make our destructor protected so that only
+ ourselves, our derivatives and our friends can delete us. It's a
+ nice compromise. */</font>
void destroy (void);
- <font color=red>/*
- Most ACE objects have an open() method. That's how you make them ready
- to do work. ACE_Event_Handler has a virtual open() method which allows us
- to create this overrride. ACE_Acceptor&lt;> will invoke this method after
- creating a new Client_Handler when a client connects. Notice that the
- parameter to open() is a void*. It just so happens that the pointer
- points to the acceptor which created us. You would like for the parameter
- to be an ACE_Acceptor&lt;>* but since ACE_Event_Handler is generic, that
- would tie it too closely to the ACE_Acceptor&lt;> set of objects. In our
- definition of open() you'll see how we get around that.
- */</font>
- int open (void *_acceptor);
-
- <font color=red>/*
- When an ACE_Task&lt;> 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.
- */</font>
- int close(u_long flags = 0);
-
- <font color=red>/*
- 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
- clean itself up. Since an event handler can be registered for more than
- one type of callback, the callback mask is provided to inform
- handle_close() exactly which method failed. That way, you don't have to
- maintain state information between your handle_* method calls. The _handle
- parameter is explained below...
- As a side-effect, the reactor will also invoke remove_handler()
- for the object on the mask that caused the -1 return. This means
- that we don't have to do that ourselves!
- */</font>
- int handle_close (ACE_HANDLE _handle, ACE_Reactor_Mask _mask);
-
- <font color=red>/*
- When we register with the reactor, we're going to tell it that we want to
- be notified of READ events. When the reactor sees that there is read
- activity for us, our handle_input() will be invoked. The _handleg
- provided is the handle (file descriptor in Unix) of the actual connection
- causing the activity. Since we're derived from ACE_Svc_Handler&lt;> and it
- maintains it's own peer (ACE_SOCK_Stream) object, this is redundant for
- us. However, if we had been derived directly from ACE_Event_Handler, we
- may have chosen not to contain the peer. In that case, the _handleg
- would be important to us for reading the client's data.
- */</font>
- int handle_input (ACE_HANDLE _handle);
+ <font color=red>/* Most ACE objects have an open() method. That's how you make them
+ ready to do work. ACE_Event_Handler has a virtual open() method
+ which allows us to create this overrride. ACE_Acceptor&lt;> will
+ invoke this method after creating a new Client_Handler when a
+ client connects. Notice that the parameter to open() is a void*.
+ It just so happens that the pointer points to the acceptor which
+ created us. You would like for the parameter to be an
+ ACE_Acceptor&lt;>* but since ACE_Event_Handler is generic, that would
+ tie it too closely to the ACE_Acceptor&lt;> set of objects. In our
+ definition of open() you'll see how we get around that. */</font>
+ int open (void *acceptor);
+
+ <font color=red>/* When an ACE_Task&lt;> 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. */</font>
+ int close (u_long flags = 0);
+
+ <font color=red>/* 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 clean itself
+ up. Since an event handler can be registered for more than one
+ type of callback, the callback mask is provided to inform
+ handle_close() exactly which method failed. That way, you don't
+ have to maintain state information between your handle_* method
+ calls. The &lt;handle> parameter is explained below... As a
+ side-effect, the reactor will also invoke remove_handler() for the
+ object on the mask that caused the -1 return. This means that we
+ don't have to do that ourselves! */</font>
+ int handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask mask);
+
+ <font color=red>/* When we register with the reactor, we're going to tell it that we
+ want to be notified of READ events. When the reactor sees that
+ there is read activity for us, our handle_input() will be
+ invoked. The _handleg provided is the handle (file descriptor in
+ Unix) of the actual connection causing the activity. Since we're
+ derived from ACE_Svc_Handler&lt;> and it maintains it's own peer
+ (ACE_SOCK_Stream) object, this is redundant for us. However, if
+ we had been derived directly from ACE_Event_Handler, we may have
+ chosen not to contain the peer. In that case, the &lt;handle> would
+ be important to us for reading the client's data. */</font>
+ int handle_input (ACE_HANDLE handle);
protected:
- <font color=red>/*
- If the Client_Acceptor which created us has chosen a thread-per-connection
- strategy then our open() method will activate us into a dedicate thread.
- The svc() method will then execute in that thread performing some of the
- functions we used to leave up to the reactor.
- */</font>
- int svc(void);
-
- <font color=red>/*
- This has nothing at all to do with ACE. I've added this here as a worker
- function which I will call from handle_input(). That allows me to
- introduce concurrencly in later tutorials with a no changes to the worker
- function. You can think of process() as application-level code and
- everything elase as application-framework code.
- */</font>
- int process (char *_rdbuf, int _rdbuf_len);
-
- <font color=red>/*
- We don't really do anything in our destructor but we've declared it to be
- protected to prevent casual deletion of this object. As I said above, I
- really would prefer that everyone goes through the destroy() method to get
- rid of us.
- */</font>
- ~Client_Handler (void);
-
- <font color=red>/*
- When we get to the definition of Client_Handler we'll see that there are
- several places where we go back to the Client_Acceptor for information.
- It is generally a good idea to do that through an accesor rather than
- using the member variable directly.
- */</font>
- Client_Acceptor * client_acceptor( void )
- { return this->client_acceptor_; }
-
- <font color=red>/*
- And since you shouldn't access a member variable directly, neither should you
- set (mutate) it. Although it might seem silly to do it this way, you'll thank
- yourself for it later.
- */</font>
- void client_acceptor( Client_Acceptor * _client_acceptor )
- { this->client_acceptor_ = _client_acceptor; }
-
- <font color=red>/*
- The concurrency() accessor tells us the current concurrency strategy. It actually
- queries the Client_Acceptor for it but by having the accessor in place, we could
- change our implementation without affecting everything that needs to know.
- */</font>
- int concurrency(void);
-
- <font color=red>/*
- Likewise for access to the Thread_Pool that we belong to.
- */</font>
- Thread_Pool * thread_pool(void);
-
-
- Client_Acceptor * client_acceptor_;
-
- <font color=red>/*
- For some reason I didn't create accessor/mutator methods for this. So much for
- consistency....
-
- This variable is used to remember the thread in which we were created: the "<font color=green>creator</font>"
- thread in other words. handle_input() needs to know if it is operating in the
- main reactor thread (which is the one that created us) or if it is operating in
- one of the thread pool threads. More on this when we get to handle_input().
- */</font>
- ACE_thread_t creator_;
+ <font color=red>/* If the Client_Acceptor which created us has chosen a
+ thread-per-connection strategy then our open() method will
+ activate us into a dedicate thread. The svc() method will then
+ execute in that thread performing some of the functions we used to
+ leave up to the reactor. */</font>
+ int svc (void);
+
+ <font color=red>/* This has nothing at all to do with ACE. I've added this here as
+ a worker function which I will call from handle_input(). That
+ allows me to introduce concurrencly in later tutorials with a no
+ changes to the worker function. You can think of process() as
+ application-level code and everything elase as
+ application-framework code. */</font>
+ int process (char *rdbuf, int rdbuf_len);
+
+ <font color=red>/* We don't really do anything in our destructor but we've declared
+ it to be protected to prevent casual deletion of this object. As
+ I said above, I really would prefer that everyone goes through the
+ destroy() method to get rid of us. */</font>
+ ~Client_Handler (void);
+
+ <font color=red>/* When we get to the definition of Client_Handler we'll see that
+ there are several places where we go back to the Client_Acceptor
+ for information. It is generally a good idea to do that through
+ an accesor rather than using the member variable directly. */</font>
+ Client_Acceptor *client_acceptor (void)
+ {
+ return this->client_acceptor_;
+ }
+
+ <font color=red>/* And since you shouldn't access a member variable directly,
+ neither should you set (mutate) it. Although it might seem silly
+ to do it this way, you'll thank yourself for it later. */</font>
+ void client_acceptor (Client_Acceptor *client_acceptor)
+ {
+ this->client_acceptor_ = _client_acceptor;
+ }
+
+ <font color=red>/* The concurrency() accessor tells us the current concurrency
+ strategy. It actually queries the Client_Acceptor for it but by
+ having the accessor in place, we could change our implementation
+ without affecting everything that needs to know. */</font>
+ int concurrency (void);
+
+ <font color=red>/* Likewise for access to the Thread_Pool that we belong to. */</font>
+ Thread_Pool * thread_pool (void);
+
+ Client_Acceptor *client_acceptor_;
+
+ <font color=red>/* For some reason I didn't create accessor/mutator methods for
+ this. So much for consistency....
+
+ This variable is used to remember the thread in which we were
+ created: the "<font color=green>creator</font>" thread in other words. handle_input()
+ needs to know if it is operating in the main reactor thread (which
+ is the one that created us) or if it is operating in one of the
+ thread pool threads. More on this when we get to handle_input(). */</font>
+ ACE_thread_t creator_;
};
-<font color=blue>#endif</font> <font color=red>// CLIENT_HANDLER_H</font>
+<font color=blue>#endif</font> <font color=red>/* CLIENT_HANDLER_H */</font>
</PRE>
<HR WIDTH="100%">
diff --git a/docs/tutorials/007/page07.html b/docs/tutorials/007/page07.html
index d200d598791..6da001738a2 100644
--- a/docs/tutorials/007/page07.html
+++ b/docs/tutorials/007/page07.html
@@ -21,108 +21,95 @@ to make so few changes to the rest of the code.
<HR WIDTH="100%"><FONT FACE="Arial,Helvetica"></FONT>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>THREAD_POOL_H</font>
<font color=blue>#define</font> <font color=purple>THREAD_POOL_H</font>
-<font color=red>/*
- In order to implement a thread pool, we have to have an object that can create
- a thread. The ACE_Task&lt;> is the basis for doing just such a thing.
- */</font>
+<font color=red>/* In order to implement a thread pool, we have to have an object that
+ can create a thread. The ACE_Task&lt;> is the basis for doing just
+ such a thing. */</font>
<font color=blue>#include</font> "<font color=green>ace/Task.h</font>"
<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>)
# pragma once
<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font>
-<font color=red>/*
- We need a forward reference for ACE_Event_Handler so that our enqueue() method
- can accept a pointer to one.
- */</font>
+<font color=red>/* We need a forward reference for ACE_Event_Handler so that our
+ enqueue() method can accept a pointer to one. */</font>
class ACE_Event_Handler;
-<font color=red>/*
- Although we modified the rest of our program to make use of the thread pool
- implementation, if you look closely you'll see that the changes were rather
- minor. The "<font color=green>ACE way</font>" is generally to create a helper object that abstracts
- away the details not relevant to your application. That's what I'm trying
- to do here by creating the Thread_Pool object.
- */</font>
+<font color=red>/* Although we modified the rest of our program to make use of the
+ thread pool implementation, if you look closely you'll see that the
+ changes were rather minor. The "<font color=green>ACE way</font>" is generally to create a
+ helper object that abstracts away the details not relevant to your
+ application. That's what I'm trying to do here by creating the
+ Thread_Pool object. */</font>
class Thread_Pool : public ACE_Task&lt;ACE_MT_SYNCH>
{
public:
-
typedef ACE_Task&lt;ACE_MT_SYNCH> inherited;
- <font color=red>/*
- Provide an enumeration for the default pool size. By doing this, other objects
- can use the value when they want a default.
- */</font>
- enum size_t
- {
- default_pool_size_ = 5
- };
-
- <font color=red>// Basic constructor</font>
- Thread_Pool(void);
-
- <font color=red>/*
- Opening the thread pool causes one or more threads to be activated. When activated,
- they all execute the svc() method declared below.
- */</font>
- int open( int _pool_size = default_pool_size_ );
-
- <font color=red>/*
- Some compilers will complain that our open() above attempts to
- override a virtual function in the baseclass. We have no
- intention of overriding that method but in order to keep the
- compiler quiet we have to add this method as a pass-thru to the
- baseclass method.
- */</font>
- virtual int open(void * _void_data)
- { return <font color=#008888>inherited::open</font>(_void_data); }
-
- <font color=red>/*
- */</font>
- int close( u_long flags = 0 );
-
- <font color=red>/*
- To use the thread pool, you have to put some unit of work into it. Since we're
- dealing with event handlers (or at least their derivatives), I've chosen to provide
- an enqueue() method that takes a pointer to an ACE_Event_Handler. The handler's
- handle_input() method will be called, so your object has to know when it is being
- called by the thread pool.
- */</font>
- int enqueue( ACE_Event_Handler * _handler );
-
- <font color=red>/*
- Another handy ACE template is ACE_Atomic_Op&lt;>. When parameterized, this allows
- is to have a thread-safe counting object. The typical arithmetic operators are
- all internally thread-safe so that you can share it across threads without worrying
- about any contention issues.
- */</font>
- typedef ACE_Atomic_Op&lt;ACE_Mutex,int> counter_t;
+ <font color=red>/* Provide an enumeration for the default pool size. By doing this,
+ other objects can use the value when they want a default. */</font>
+ enum size_t
+ {
+ default_pool_size_ = 5
+ };
+
+ <font color=red>// Basic constructor</font>
+ Thread_Pool (void);
+
+ <font color=red>/* Opening the thread pool causes one or more threads to be
+ activated. When activated, they all execute the svc() method
+ declared below. */</font>
+ int open (int pool_size = default_pool_size);
+
+ <font color=red>/* Some compilers will complain that our open() above attempts to
+ override a virtual function in the baseclass. We have no
+ intention of overriding that method but in order to keep the
+ compiler quiet we have to add this method as a pass-thru to the
+ baseclass method. */</font>
+ virtual int open (void *void_data)
+ {
+ return <font color=#008888>inherited::open</font> (void_data);
+ }
+
+ <font color=red>/*
+ */</font>
+ virtual int close (u_long flags = 0);
+
+ <font color=red>/* To use the thread pool, you have to put some unit of work into
+ it. Since we're dealing with event handlers (or at least their
+ derivatives), I've chosen to provide an enqueue() method that
+ takes a pointer to an ACE_Event_Handler. The handler's
+ handle_input() method will be called, so your object has to know
+ when it is being called by the thread pool. */</font>
+ int enqueue (ACE_Event_Handler *handler);
+
+ <font color=red>/* Another handy ACE template is ACE_Atomic_Op&lt;>. When
+ parameterized, this allows is to have a thread-safe counting
+ object. The typical arithmetic operators are all internally
+ thread-safe so that you can share it across threads without
+ worrying about any contention issues. */</font>
+ typedef ACE_Atomic_Op&lt;ACE_Mutex, int> counter_t;
protected:
- <font color=red>/*
- Our svc() method will dequeue the enqueued event handler objects and invoke the
- handle_input() method on each. Since we're likely running in more than one thread,
- idle threads can take work from the queue while other threads are busy executing
- handle_input() on some object.
- */</font>
- int svc(void);
-
- <font color=red>/*
- We use the atomic op to keep a count of the number of threads in which our svc()
- method is running. This is particularly important when we want to close() it down!
- */</font>
- counter_t active_threads_;
+ <font color=red>/* Our svc() method will dequeue the enqueued event handler objects
+ and invoke the handle_input() method on each. Since we're likely
+ running in more than one thread, idle threads can take work from
+ the queue while other threads are busy executing handle_input() on
+ some object. */</font>
+ int svc (void);
+
+ <font color=red>/* We use the atomic op to keep a count of the number of threads in
+ which our svc() method is running. This is particularly important
+ when we want to close() it down! */</font>
+ counter_t active_threads_;
};
-<font color=blue>#endif</font> <font color=red>// THREAD_POOL_H</font>
+<font color=blue>#endif</font> <font color=red>/* THREAD_POOL_H */</font>
</PRE>
<HR WIDTH="100%">
diff --git a/docs/tutorials/014/page02.html b/docs/tutorials/014/page02.html
index 452f18f49df..72259699d29 100644
--- a/docs/tutorials/014/page02.html
+++ b/docs/tutorials/014/page02.html
@@ -19,7 +19,6 @@ You find pretty soon that anytime you work with ACE_Task&lt;&gt; you
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=red>// Task.h</font>
@@ -27,8 +26,6 @@ You find pretty soon that anytime you work with ACE_Task&lt;&gt; you
<font color=red>// Tutorial regarding a way to use ACE_Stream.</font>
<font color=red>//</font>
<font color=red>// written by bob mcwhirter (bob@netwrench.com)</font>
-<font color=red>//</font>
-<font color=red>//</font>
<font color=blue>#ifndef</font> <font color=purple>TASK_H</font>
<font color=blue>#define</font> <font color=purple>TASK_H</font>
@@ -42,51 +39,45 @@ typedef ACE_Task&lt;ACE_MT_SYNCH> Task_Base;
class Task : public Task_Base
{
-
public:
-
typedef Task_Base inherited;
<font color=red>// This is just good form.</font>
- Task(const char *nameOfTask,
- int numberOfThreads);
- <font color=red>// Initialize our Task with a name,</font>
- <font color=red>// and number of threads to spawn.</font>
+ Task (const char *nameOfTask,
+ int numberOfThreads);
+ <font color=red>// Initialize our Task with a name, and number of threads to spawn.</font>
- virtual ~Task(void);
+ virtual ~Task (void);
- virtual int open(void *arg);
- <font color=red>// This is provided to prevent compiler complaints</font>
- <font color=red>// about hidden virtual functions.</font>
+ virtual int open (void *arg);
+ <font color=red>// This is provided to prevent compiler complaints about hidden</font>
+ <font color=red>// virtual functions.</font>
- virtual int close(u_long flags);
+ virtual int close (u_long flags);
<font color=red>// This closes down the Task and all service threads.</font>
- virtual int put(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
- <font color=red>// This is the interface that ACE_Stream uses to</font>
- <font color=red>// communicate with our Task.</font>
+ virtual int put (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
+ <font color=red>// This is the interface that ACE_Stream uses to communicate with</font>
+ <font color=red>// our Task.</font>
- virtual int svc(void);
- <font color=red>// This is the actual service loop each of the service</font>
- <font color=red>// threads iterates through.</font>
+ virtual int svc (void);
+ <font color=red>// This is the actual service loop each of the service threads</font>
+ <font color=red>// iterates through.</font>
- const char *nameOfTask(void) const;
+ const char *nameOfTask (void) const;
<font color=red>// Returns the name of this Task.</font>
private:
-
int d_numberOfThreads;
char d_nameOfTask[64];
ACE_Barrier d_barrier;
- <font color=red>// Simple Barrier to make sure all of our service</font>
- <font color=red>// threads have entered their loop before accepting</font>
- <font color=red>// any messages.</font>
+ <font color=red>// Simple Barrier to make sure all of our service threads have</font>
+ <font color=red>// entered their loop before accepting any messages.</font>
};
-
-<font color=blue>#endif</font> <font color=red>// TASK_H</font>
+<font color=blue>#endif</font> <font color=red>/* TASK_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/014/page04.html b/docs/tutorials/014/page04.html
index e4ca848ff76..78bb47373d0 100644
--- a/docs/tutorials/014/page04.html
+++ b/docs/tutorials/014/page04.html
@@ -24,7 +24,6 @@ Read on...
<P>
<HR WIDTH="100%">
<PRE>
-
<font color=red>// $Id$</font>
<font color=red>// EndTask.h</font>
@@ -56,54 +55,64 @@ Read on...
<font color=red>// All this Task does is release the Message_Block</font>
<font color=red>// and return 0. It's a suitable black-hole.</font>
-
class EndTask : public Task
{
-
public:
-
typedef Task inherited;
- EndTask(const char *nameOfTask) :
- inherited(nameOfTask, 0) {
-
- <font color=red>// when we get open()'d, it with 0 threads</font>
- <font color=red>// since there is actually no processing to do.</font>
+ EndTask (const char *nameOfTask): inherited (nameOfTask, 0)
+ {
+ <font color=red>// when we get open()'d, it with 0 threads since there is actually</font>
+ <font color=red>// no processing to do.</font>
- cerr &lt;&lt; __LINE__ &lt;&lt; "<font color=green> </font>" &lt;&lt; __FILE__ &lt;&lt; endl;
- };
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Line: %d, File: %s\n</font>",
+ __LINE__,
+ __FILE__));
+ }
- virtual int open(void *)
+ virtual int open (void *)
{
- cerr &lt;&lt; __LINE__ &lt;&lt; "<font color=green> </font>" &lt;&lt; __FILE__ &lt;&lt; endl;
- return 0;
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Line: %d, File: %s\n</font>",
+ __LINE__,
+ __FILE__));
+ return 0;
}
- virtual int open(void)
+ virtual int open (void)
{
- cerr &lt;&lt; __LINE__ &lt;&lt; "<font color=green> </font>" &lt;&lt; __FILE__ &lt;&lt; endl;
- return 0;
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Line: %d, File: %s\n</font>",
+ __LINE__,
+ __FILE__));
+ return 0;
}
- virtual ~EndTask(void) {
- };
-
- virtual int put(ACE_Message_Block *message,
- ACE_Time_Value *timeout) {
-
- cerr &lt;&lt; __LINE__ &lt;&lt; "<font color=green> </font>" &lt;&lt; __FILE__ &lt;&lt; endl;
- ACE_UNUSED_ARG(timeout);
+ virtual ~EndTask(void)
+ {
+ }
- <font color=red>// we don't have anything to do, so</font>
- <font color=red>// release() the message.</font>
- ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>EndTask::put</font>() -- releasing Message_Block\n</font>", this->nameOfTask()));
- message->release();
+ virtual int put (ACE_Message_Block *message,
+ ACE_Time_Value *timeout)
+ {
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Line: %d, File: %s\n</font>",
+ __LINE__,
+ __FILE__));
+ ACE_UNUSED_ARG (timeout);
+
+ <font color=red>// we don't have anything to do, so release() the message.</font>
+ ACE_DEBUG ((LM_DEBUG,
+ "<font color=green>(%P|%t) %s <font color=#008888>EndTask::put</font>() -- releasing Message_Block\n</font>",
+ this->nameOfTask ()));
+ message->release ();
return 0;
- };
+ }
};
-<font color=blue>#endif</font> <font color=red>// ENDTASK_H</font>
+<font color=blue>#endif</font> <font color=red>/* ENDTASK_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/014/page05.html b/docs/tutorials/014/page05.html
index fa5c4fd132e..a5d2160b2f8 100644
--- a/docs/tutorials/014/page05.html
+++ b/docs/tutorials/014/page05.html
@@ -52,6 +52,7 @@ Once the stream of modules containing tasks is all setup then we can
<font color=blue>#include</font> &lt;ace/Module.h>
<font color=blue>#include</font> &lt;ace/Stream.h>
+<font color=blue>#include</font> &lt;ace/streams.h>
<font color=red>// These are the neccessary ACE headers.</font>
diff --git a/docs/tutorials/015/page03.html b/docs/tutorials/015/page03.html
index 76f57fab17f..04f091d497d 100644
--- a/docs/tutorials/015/page03.html
+++ b/docs/tutorials/015/page03.html
@@ -19,7 +19,6 @@ The Client object is designed to hide all of the messy connection
converting and sending/receiving the data.
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CLIENT_H</font>
@@ -41,58 +40,58 @@ class ACE_Message_Block;
class Client
{
public:
- <font color=red>// Provide the server information when constructing the</font>
- <font color=red>// object. This could (and probably should) be moved to the</font>
- <font color=red>// open() method.</font>
- Client( u_short _port, const char * _server );
+ <font color=red>// Provide the server information when constructing the</font>
+ <font color=red>// object. This could (and probably should) be moved to the</font>
+ <font color=red>// open() method.</font>
+ Client (u_short port,
+ const char *server);
- <font color=red>// Cleanup...</font>
- ~Client(void);
+ <font color=red>// Cleanup...</font>
+ ~Client (void);
- <font color=red>// Open the connection to the server.</font>
- int open(void);
+ <font color=red>// Open the connection to the server.</font>
+ int open (void);
- <font color=red>// Close the connection to the server. Be sure to do this</font>
- <font color=red>// before you let the Client go out of scope.</font>
- int close(void);
+ <font color=red>// Close the connection to the server. Be sure to do this</font>
+ <font color=red>// before you let the Client go out of scope.</font>
+ int close (void);
- <font color=red>// Put a message to the server. The Client assumes ownership</font>
- <font color=red>// of _message at that point and will release() it when done.</font>
- <font color=red>// Do not use _message after passing it to put().</font>
- int put( ACE_Message_Block * _message );
+ <font color=red>// Put a message to the server. The Client assumes ownership of</font>
+ <font color=red>// &lt;message> at that point and will release() it when done. Do not</font>
+ <font color=red>// use &lt;message> after passing it to put().</font>
+ int put (ACE_Message_Block *message);
- <font color=red>// Get a response from the server. The caller becomes the</font>
- <font color=red>// owner of _response after this call and is responsible for</font>
- <font color=red>// invoking release() when done.</font>
- int get( ACE_Message_Block * & _response );
+ <font color=red>// Get a response from the server. The caller becomes the owner of</font>
+ <font color=red>// &lt;response> after this call and is responsible for invoking</font>
+ <font color=red>// release() when done.</font>
+ int get (ACE_Message_Block *&response);
private:
- <font color=red>// Protocol_Stream hides the protocol conformance details from</font>
- <font color=red>// us.</font>
- Protocol_Stream stream_;
+ <font color=red>// Protocol_Stream hides the protocol conformance details from us.</font>
+ Protocol_Stream stream_;
- <font color=red>// We create a connection on the peer_ and then pass ownership</font>
- <font color=red>// of it to the protocol stream.</font>
- ACE_SOCK_Stream peer_;
+ <font color=red>// We create a connection on the peer_ and then pass ownership of it</font>
+ <font color=red>// to the protocol stream.</font>
+ ACE_SOCK_Stream peer_;
- <font color=red>// Endpoing information saved by the constructor for use by open().</font>
- u_short port_;
- const char * server_;
+ <font color=red>// Endpoing information saved by the constructor for use by open().</font>
+ u_short port_;
+ const char *server_;
- <font color=red>// Accessors for the complex member variables.</font>
+ <font color=red>// Accessors for the complex member variables.</font>
- Protocol_Stream & stream(void)
- {
- return this->stream_;
- }
+ Protocol_Stream &stream (void)
+ {
+ return this->stream_;
+ }
- ACE_SOCK_Stream & peer(void)
- {
- return this->peer_;
- }
+ ACE_SOCK_Stream &peer (void)
+ {
+ return this->peer_;
+ }
};
-<font color=blue>#endif</font> <font color=red>// CLIENT_H</font>
+<font color=blue>#endif</font> <font color=red>/* CLIENT_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page04.html b/docs/tutorials/015/page04.html
index 866fede9c52..f4c655e4f8f 100644
--- a/docs/tutorials/015/page04.html
+++ b/docs/tutorials/015/page04.html
@@ -85,9 +85,10 @@ Ok, that's it for the client. We've seen a very simple main()
<P>
For a quick look back:
<UL>
+<LI><A HREF="Makefile.client">client Makefile</A>
<LI><A HREF="client.cpp">client.cpp</A>
-<LI><A HREF="Client.h">Client.h</A>
-<LI><A HREF="Client.cpp">Client.cpp</A>
+<LI><A HREF="Client_i.h">Client_i.h</A>
+<LI><A HREF="Client_i.cpp">Client_i.cpp</A>
</UL>
<P>
Now we'll move on and examine the server counter-part of our client.
diff --git a/docs/tutorials/015/page06.html b/docs/tutorials/015/page06.html
index 5fc8f8eca24..82b28a3f572 100644
--- a/docs/tutorials/015/page06.html
+++ b/docs/tutorials/015/page06.html
@@ -22,7 +22,6 @@ only be one Server instance but since you can't provide a TCP/IP port,
that's probably a valid assumption!
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>SERVER_H</font>
@@ -40,40 +39,39 @@ that's probably a valid assumption!
<font color=red>/* Anytime I have templates I try to remember to create a typedef for
the parameterized object. It makes for much less typing later!
*/</font>
-typedef ACE_Acceptor &lt; Handler, ACE_SOCK_ACCEPTOR > Acceptor;
+typedef ACE_Acceptor &lt;Handler, ACE_SOCK_ACCEPTOR> Acceptor;
class Server
{
public:
- <font color=red>// Our simple constructor takes no parameters. To make the</font>
- <font color=red>// server a bit more useful, you may want to pass in the</font>
- <font color=red>// TCP/IP port to be used by the acceptor.</font>
- Server(void);
- ~Server(void);
+ <font color=red>// Our simple constructor takes no parameters. To make the</font>
+ <font color=red>// server a bit more useful, you may want to pass in the</font>
+ <font color=red>// TCP/IP port to be used by the acceptor.</font>
+ Server (void);
+ ~Server (void);
- <font color=red>// Open the server for business</font>
- int open(void);
+ <font color=red>// Open the server for business</font>
+ int open (void);
- <font color=red>// Close all server instances by setting the finished_ flag.</font>
- <font color=red>// Actually, the way this class is written, you can only have</font>
- <font color=red>// one instance.</font>
- static int close(void);
+ <font color=red>// Close all server instances by setting the finished_ flag.</font>
+ <font color=red>// Actually, the way this class is written, you can only have</font>
+ <font color=red>// one instance.</font>
+ static int close (void);
- <font color=red>// Run the server's main loop. The use of the gloabl</font>
- <font color=red>// ACE_Reactor by this method is what limits us to one Server</font>
- <font color=red>// instance.</font>
- int run(void);
+ <font color=red>// Run the server's main loop. The use of the gloabl ACE_Reactor by</font>
+ <font color=red>// this method is what limits us to one Server instance.</font>
+ int run (void);
private:
- <font color=red>// This will accept client connection requests and instantiate</font>
- <font color=red>// a Handler object for each new connection.</font>
- Acceptor acceptor_;
+ <font color=red>// This will accept client connection requests and instantiate a</font>
+ <font color=red>// Handler object for each new connection.</font>
+ Acceptor acceptor_;
- <font color=red>// Our shutdown flag</font>
- static sig_atomic_t finished_;
+ <font color=red>// Our shutdown flag</font>
+ static sig_atomic_t finished_;
};
-<font color=blue>#endif</font> <font color=red>// SERVER_H</font>
+<font color=blue>#endif</font> <font color=red>/* SERVER_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page07.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page08.html b/docs/tutorials/015/page08.html
index ffa7d9c63c9..ed60a976839 100644
--- a/docs/tutorials/015/page08.html
+++ b/docs/tutorials/015/page08.html
@@ -23,7 +23,6 @@ collect data from the peer and pass it along to another object for
processing. Again, keep it simple and delegate authority.
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>HANDLER_H</font>
@@ -41,54 +40,50 @@ processing. Again, keep it simple and delegate authority.
<font color=red>/* Just your basic event handler. We use ACE_Svc_Handler&lt;> as a
baseclass so that it can maintain the peer() and other details for
us. We're not going to activate() this object, so we can get away
- with the NULL synch choice.
-*/</font>
-class Handler : public ACE_Svc_Handler &lt; ACE_SOCK_STREAM, ACE_NULL_SYNCH >
+ with the NULL synch choice. */</font>
+class Handler : public ACE_Svc_Handler &lt;ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
public:
+ Handler (void);
+ ~Handler (void);
- Handler(void);
- ~Handler(void);
-
- <font color=red>// Called by the acceptor when we're created in response to a</font>
- <font color=red>// client connection.</font>
- int open (void *);
+ <font color=red>// Called by the acceptor when we're created in response to a client</font>
+ <font color=red>// connection.</font>
+ int open (void *);
- <font color=red>// Called when it's time for us to be deleted. We take care</font>
- <font color=red>// of removing ourselves from the reactor and shutting down</font>
- <font color=red>// the peer() connectin.</font>
- void destroy (void);
+ <font color=red>// Called when it's time for us to be deleted. We take care of</font>
+ <font color=red>// removing ourselves from the reactor and shutting down the peer()</font>
+ <font color=red>// connectin.</font>
+ void destroy (void);
- <font color=red>// Called when it's time for us to go away. There are subtle</font>
- <font color=red>// differences between destroy() and close() so don't try to</font>
- <font color=red>// use either for all cases.</font>
- int close (u_long);
+ <font color=red>// Called when it's time for us to go away. There are subtle</font>
+ <font color=red>// differences between destroy() and close() so don't try to use</font>
+ <font color=red>// either for all cases.</font>
+ int close (u_long);
protected:
+ <font color=red>// Respond to peer() activity.</font>
+ int handle_input (ACE_HANDLE);
- <font color=red>// Respond to peer() activity.</font>
- int handle_input (ACE_HANDLE);
-
- <font color=red>// This will be called when handle_input() returns a failure</font>
- <font color=red>// code. That's our signal that it's time to begin the</font>
- <font color=red>// shutdown process.</font>
- int handle_close(ACE_HANDLE, ACE_Reactor_Mask _mask);
-
+ <font color=red>// This will be called when handle_input() returns a failure code.</font>
+ <font color=red>// That's our signal that it's time to begin the shutdown process.</font>
+ int handle_close (ACE_HANDLE,
+ ACE_Reactor_Mask mask);
private:
- <font color=red>// Like the Client, we have to abide by the protocol</font>
- <font color=red>// requirements. We use a local Protocol_Stream object to</font>
- <font color=red>// take care of those details. For us, I/O then just becomes</font>
- <font color=red>// a matter of interacting with the stream.</font>
- Protocol_Stream stream_;
+ <font color=red>// Like the Client, we have to abide by the protocol requirements.</font>
+ <font color=red>// We use a local Protocol_Stream object to take care of those</font>
+ <font color=red>// details. For us, I/O then just becomes a matter of interacting</font>
+ <font color=red>// with the stream.</font>
+ Protocol_Stream stream_;
- Protocol_Stream & stream(void)
- {
- return this->stream_;
- }
+ Protocol_Stream &stream (void)
+ {
+ return this->stream_;
+ }
};
-<font color=blue>#endif</font> <font color=red>// HANDLER_H</font>
+<font color=blue>#endif</font> <font color=red>/* HANDLER_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page09.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page09.html b/docs/tutorials/015/page09.html
index cd3961df766..558ba8ce8c3 100644
--- a/docs/tutorials/015/page09.html
+++ b/docs/tutorials/015/page09.html
@@ -213,12 +213,12 @@ cause confusion. We're going to discuss that mystery now but before
we do here's the list of server files if you want to review:
<UL>
+<LI><A HREF="Makefile.server">Server Makefile</A>
<LI><A HREF="server.cpp">server.cpp</A>
-<LI><A HREF="Server.h">Server.h</A>
-<LI><A HREF="Server.cpp">Server.cpp</A>
+<LI><A HREF="Server_i.h">Server_i.h</A>
+<LI><A HREF="Server_i.cpp">Server_i.cpp</A>
<LI><A HREF="Handler.h">Handler.h</A>
<LI><A HREF="Handler.cpp">Handler.cpp</A>
-<LI><A HREF="Makefile.server">Server Makefile</A>
</UL>
<P>
<P><HR WIDTH="100%">
diff --git a/docs/tutorials/015/page10.html b/docs/tutorials/015/page10.html
index 476dfe3c7a0..5dc3711f0ba 100644
--- a/docs/tutorials/015/page10.html
+++ b/docs/tutorials/015/page10.html
@@ -35,7 +35,6 @@ going on here.
<P><center><img src="stream.gif"></center></p>
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>PROTOCOL_STREAM_H</font>
@@ -63,64 +62,65 @@ class Protocol_Task;
class Protocol_Stream
{
public:
- Protocol_Stream(void);
- ~Protocol_Stream(void);
-
- <font color=red>// Provide the stream with an ACE_SOCK_Stream on which it can</font>
- <font color=red>// communicate. If _reader is non-null, it will be added as</font>
- <font color=red>// the reader task just below the stream head so that it can</font>
- <font color=red>// process data read from the peer.</font>
- int open( ACE_SOCK_Stream & _peer, Protocol_Task * _reader = 0 );
-
- <font color=red>// Close the stream. All of the tasks & modules will also be closed.</font>
- int close(void);
-
- <font color=red>// putting data onto the stream will pass it through all</font>
- <font color=red>// protocol levels and send it to the peer.</font>
- int put( ACE_Message_Block * & _message, ACE_Time_Value *
- _timeout = 0 );
-
- <font color=red>// get will cause the Recv task (at the tail of the stream) to</font>
- <font color=red>// read some data from the peer and pass it upstream. The</font>
- <font color=red>// message block is then taken from the stream reader task's</font>
- <font color=red>// message queue.</font>
- int get( ACE_Message_Block * & _response, ACE_Time_Value *
- _timeout = 0 );
-
- <font color=red>// Tell the Recv task to read some data and send it upstream.</font>
- <font color=red>// The data will pass through the protocol tasks and be queued</font>
- <font color=red>// into the stream head reader task's message queue. If</font>
- <font color=red>// you've installed a _reader in open() then that task's</font>
- <font color=red>// recv() method will see the message and may consume it</font>
- <font color=red>// instead of passing it to the stream head for queueing.</font>
- int get(void);
-
- ACE_SOCK_Stream & peer(void)
- {
- return this->peer_;
- }
+ Protocol_Stream (void);
+ ~Protocol_Stream (void);
+
+ <font color=red>// Provide the stream with an ACE_SOCK_Stream on which it can</font>
+ <font color=red>// communicate. If _reader is non-null, it will be added as the</font>
+ <font color=red>// reader task just below the stream head so that it can process</font>
+ <font color=red>// data read from the peer.</font>
+ int open (ACE_SOCK_Stream &peer,
+ Protocol_Task *reader = 0);
+
+ <font color=red>// Close the stream. All of the tasks & modules will also be</font>
+ <font color=red>// closed.</font>
+ int close (void);
+
+ <font color=red>// putting data onto the stream will pass it through all protocol</font>
+ <font color=red>// levels and send it to the peer.</font>
+ int put (ACE_Message_Block *&message,
+ ACE_Time_Value *timeout = 0);
+
+ <font color=red>// get will cause the Recv task (at the tail of the stream) to read</font>
+ <font color=red>// some data from the peer and pass it upstream. The message block</font>
+ <font color=red>// is then taken from the stream reader task's message queue.</font>
+ int get (ACE_Message_Block *&response,
+ ACE_Time_Value *timeout = 0);
+
+ <font color=red>// Tell the Recv task to read some data and send it upstream. The</font>
+ <font color=red>// data will pass through the protocol tasks and be queued into the</font>
+ <font color=red>// stream head reader task's message queue. If you've installed a</font>
+ <font color=red>// _reader in open() then that task's recv() method will see the</font>
+ <font color=red>// message and may consume it instead of passing it to the stream</font>
+ <font color=red>// head for queueing.</font>
+ int get (void);
+
+ ACE_SOCK_Stream &peer (void)
+ {
+ return this->peer_;
+ }
private:
- <font color=red>// Our peer connection</font>
- ACE_SOCK_Stream peer_;
+ <font color=red>// Our peer connection</font>
+ ACE_SOCK_Stream peer_;
- <font color=red>// The stream managing the various protocol tasks</font>
- Stream stream_;
+ <font color=red>// The stream managing the various protocol tasks</font>
+ Stream stream_;
- <font color=red>// A task which is capable of receiving data on a socket.</font>
- <font color=red>// Note that this is only useful by client-side applications.</font>
- Recv * recv_;
+ <font color=red>// A task which is capable of receiving data on a socket.</font>
+ <font color=red>// Note that this is only useful by client-side applications.</font>
+ Recv *recv_;
- Stream & stream(void)
- {
- return this->stream_;
- }
+ Stream &stream (void)
+ {
+ return this->stream_;
+ }
- <font color=red>// Install the protocol tasks into the stream.</font>
- int open(void);
+ <font color=red>// Install the protocol tasks into the stream.</font>
+ int open (void);
};
-<font color=blue>#endif</font> <font color=red>// PROTOCOL_STREAM_H</font>
+<font color=blue>#endif</font> <font color=red>/* PROTOCOL_STREAM_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page11.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page11.html b/docs/tutorials/015/page11.html
index 7b5757c1ef4..3a636df9fdb 100644
--- a/docs/tutorials/015/page11.html
+++ b/docs/tutorials/015/page11.html
@@ -19,7 +19,6 @@ set of protocol objects that will manipulate the data. Our primary
concern in this file is to get everything in the correct order!
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#include</font> "<font color=green>Protocol_Stream.h</font>"
@@ -46,14 +45,12 @@ typedef ACE_Thru_Task&lt;ACE_MT_SYNCH> Thru_Task;
<font color=red>/* Do-nothing constructor and destructor
*/</font>
-<font color=#008888>Protocol_Stream::Protocol_Stream</font>( void )
+<font color=#008888>Protocol_Stream::Protocol_Stream</font> (void)
{
- ;
}
-<font color=#008888>Protocol_Stream::~Protocol_Stream</font>( void )
+<font color=#008888>Protocol_Stream::~Protocol_Stream</font> (void)
{
- ;
}
<font color=red>/* Even opening the stream is rather simple. The important thing to
@@ -61,134 +58,151 @@ typedef ACE_Thru_Task&lt;ACE_MT_SYNCH> Thru_Task;
at the tail (eg -- most downstream) end of things when you're
done.
*/</font>
-int <font color=#008888>Protocol_Stream::open</font>( ACE_SOCK_Stream & _peer, Protocol_Task * _reader )
+int
+<font color=#008888>Protocol_Stream::open</font> (ACE_SOCK_Stream &peer,
+ Protocol_Task *reader)
{
- <font color=red>// Initialize our peer() to read/write the socket we're given</font>
- peer_.set_handle( _peer.get_handle() );
-
- <font color=red>// Construct (and remember) the Recv object so that we can</font>
- <font color=red>// read from the peer().</font>
- recv_ = new Recv( peer() );
-
- <font color=red>// Add the transmit and receive tasks to the head of the</font>
- <font color=red>// stream. As we add more modules these will get pushed</font>
- <font color=red>// downstream and end up nearest the tail by the time we're</font>
- <font color=red>// done.</font>
- if( stream().push( new Module( "<font color=green>Xmit/Recv</font>", new Xmit( peer() ), recv_ ) ) == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( xmit/recv )</font>"), -1);
- }
-
- <font color=red>// Add any other protocol tasks to the stream. Each one is</font>
- <font color=red>// added at the head. The net result is that Xmit/Recv are at </font>
- <font color=red>// the tail.</font>
- if( this->open() == -1 )
- {
- return(-1);
- }
-
- <font color=red>// If a reader task was provided then push that in as the</font>
- <font color=red>// upstream side of the next-to-head module. Any data read</font>
- <font color=red>// from the peer() will be sent through here last. Server</font>
- <font color=red>// applications will typically use this task to do the actual</font>
- <font color=red>// processing of data.</font>
- <font color=red>// Note the use of Thru_Task. Since a module must always have </font>
- <font color=red>// a pair of tasks we use this on the writter side as a no-op.</font>
- if( _reader )
+ <font color=red>// Initialize our peer() to read/write the socket we're given</font>
+ peer_.set_handle (peer.get_handle ());
+
+ <font color=red>// Construct (and remember) the Recv object so that we can read from</font>
+ <font color=red>// the peer().</font>
+ ACE_NEW_RETURN (recv_,
+ Recv (peer ()),
+ -1);
+
+ <font color=red>// Add the transmit and receive tasks to the head of the stream. As</font>
+ <font color=red>// we add more modules these will get pushed downstream and end up</font>
+ <font color=red>// nearest the tail by the time we're done.</font>
+ if (stream ().push (new Module ("<font color=green>Xmit/Recv</font>",
+ new Xmit (peer ()),
+ recv_)) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>%p\n</font>",
+ "<font color=green>stream().push(xmit/recv)</font>"),
+ -1);
+
+ <font color=red>// Add any other protocol tasks to the stream. Each one is added at</font>
+ <font color=red>// the head. The net result is that Xmit/Recv are at the tail.</font>
+ if (this->open () == -1)
+ return -1;
+
+ <font color=red>// If a reader task was provided then push that in as the upstream</font>
+ <font color=red>// side of the next-to-head module. Any data read from the peer()</font>
+ <font color=red>// will be sent through here last. Server applications will</font>
+ <font color=red>// typically use this task to do the actual processing of data.</font>
+ <font color=red>// Note the use of Thru_Task. Since a module must always have a</font>
+ <font color=red>// pair of tasks we use this on the writter side as a no-op.</font>
+ if (reader)
{
- if( stream().push( new Module( "<font color=green>Reader</font>", new Thru_Task(), _reader ) ) == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( reader )</font>"), -1);
- }
+ if (stream ().push (new Module ("<font color=green>Reader</font>",
+ new Thru_Task (),
+ reader)) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>%p\n</font>",
+ "<font color=green>stream().push(reader)</font>"),
+ -1);
}
- return(0);
+ return 0;
}
<font color=red>/* Add the necessary protocol objects to the stream. The way we're
pushing things on we will encrypt the data before compressing it.
*/</font>
-int <font color=#008888>Protocol_Stream::open</font>(void)
+int
+<font color=#008888>Protocol_Stream::open</font> (void)
{
-<font color=blue>#if defined</font>(<font color=purple>ENABLE_COMPRESSION</font>)
- if( stream().push( new Module( "<font color=green>compress</font>", new Compressor(), new Compressor() ) ) == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( comprssor )</font>"), -1);
- }
-<font color=blue>#endif</font> <font color=red>// ENABLE_COMPRESSION</font>
+<font color=blue>#if defined</font> (<font color=purple>ENABLE_COMPRESSION</font>)
+ if (stream ().push (new Module ("<font color=green>compress</font>",
+ new Compressor (),
+ new Compressor ())) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>%p\n</font>",
+ "<font color=green>stream().push(comprssor)</font>"),
+ -1);
+<font color=blue>#endif</font> <font color=red>/* ENABLE_COMPRESSION */</font>
-<font color=blue>#if defined</font>(<font color=purple>ENABLE_ENCRYPTION</font>)
- if( stream().push( new Module( "<font color=green>crypt</font>", new Crypt(), new Crypt() ) ) == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>stream().push( crypt )</font>"), -1);
- }
-<font color=blue>#endif</font> <font color=red>// ENABLE_ENCRYPTION</font>
- return( 0 );
+<font color=blue>#if defined</font> (<font color=purple>ENABLE_ENCRYPTION</font>)
+ if (stream ().push (new Module ("<font color=green>crypt</font>",
+ new Crypt (),
+ new Crypt ())) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>%p\n</font>",
+ "<font color=green>stream().push(crypt)</font>"),
+ -1);
+<font color=blue>#endif</font> <font color=red>/* ENABLE_ENCRYPTION */</font>
+ return 0;
}
<font color=red>// Closing the Protocol_Stream is as simple as closing the ACE_Stream.</font>
-int <font color=#008888>Protocol_Stream::close</font>(void)
+int
+<font color=#008888>Protocol_Stream::close</font> (void)
{
- return stream().close();
+ return stream ().close ();
}
<font color=red>// Simply pass the data directly to the ACE_Stream.</font>
-int <font color=#008888>Protocol_Stream::put</font>(ACE_Message_Block * & _message, ACE_Time_Value * _timeout )
+int
+<font color=#008888>Protocol_Stream::put</font> (ACE_Message_Block *&message,
+ ACE_Time_Value *timeout)
{
- return stream().put(_message,_timeout);
+ return stream ().put (message,
+ timeout);
}
<font color=red>/* Tell the Recv module to read some data from the peer and pass it
upstream. Servers will typically use this method in a
- handle_input() method to tell the stream to get a client's request.
-*/</font>
-int <font color=#008888>Protocol_Stream::get</font>(void)
-{
- <font color=red>// If there is no Recv module, we're in big trouble!</font>
- if( ! recv_ )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) No Recv object!\n</font>"), -1);
- }
-
- <font color=red>// This tells the Recv module to go to it's peer() and read</font>
- <font color=red>// some data. Once read, that data will be pushed upstream.</font>
- <font color=red>// If there is a reader object then it will have a chance to</font>
- <font color=red>// process the data. If not, the received data will be</font>
- <font color=red>// available in the message queue of the stream head's reader</font>
- <font color=red>// object (eg -- stream().head()->reader()->msg_queue()) and</font>
- <font color=red>// can be read with our other get() method below.</font>
- if( recv_->get() == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot queue read request\n</font>"), -1);
- }
-
- <font color=red>// For flexibility I've added an error() method to tell us if</font>
- <font color=red>// something bad has happened to the Recv object.</font>
- if( recv_->error() )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Recv object error!\n</font>"), -1);
- }
+ handle_input() method to tell the stream to get a client's request. */</font>
- return(0);
+int
+<font color=#008888>Protocol_Stream::get</font>(void)
+{
+ <font color=red>// If there is no Recv module, we're in big trouble!</font>
+ if (recv_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) No Recv object!\n</font>"),
+ -1);
+
+ <font color=red>// This tells the Recv module to go to it's peer() and read some</font>
+ <font color=red>// data. Once read, that data will be pushed upstream. If there is</font>
+ <font color=red>// a reader object then it will have a chance to process the data.</font>
+ <font color=red>// If not, the received data will be available in the message queue</font>
+ <font color=red>// of the stream head's reader object (eg --</font>
+ <font color=red>// stream().head()->reader()->msg_queue()) and can be read with our</font>
+ <font color=red>// other get() method below.</font>
+ if (recv_->get () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) Cannot queue read request\n</font>"),
+ -1);
+
+ <font color=red>// For flexibility I've added an error() method to tell us if</font>
+ <font color=red>// something bad has happened to the Recv object.</font>
+ if (recv_->error ())
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) Recv object error!\n</font>"),
+ -1);
+
+ return 0;
}
-<font color=red>/* Take a message block off of the stream head reader's message
- queue. If the queue is empty, use get() to read from the peer.
- This is most often used by client applications. Servers will
- generaly insert a reader that will prevent the data from getting
- all the way upstream to the head.
-*/</font>
-int <font color=#008888>Protocol_Stream::get</font>(ACE_Message_Block * & _response, ACE_Time_Value * _timeout )
+<font color=red>/* Take a message block off of the stream head reader's message queue.
+ If the queue is empty, use get() to read from the peer. This is
+ most often used by client applications. Servers will generaly
+ insert a reader that will prevent the data from getting all the way
+ upstream to the head. */</font>
+int
+<font color=#008888>Protocol_Stream::get</font> (ACE_Message_Block *&response,
+ ACE_Time_Value *timeout )
{
- if( stream().head()->reader()->msg_queue()->is_empty() )
- {
- if( this->get() == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P|%t) Cannot get data into the stream.\n</font>"), -1);
- }
- }
+ if (stream ().head ()->reader ()->msg_queue ()->is_empty ()
+ && this->get () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) Cannot get data into the stream.\n</font>"),
+ -1);
- return stream().head()->reader()->getq(_response,_timeout);
+ return stream ().head ()->reader ()->getq (response,
+ timeout);
}
</PRE>
<P><HR WIDTH="100%">
diff --git a/docs/tutorials/015/page12.html b/docs/tutorials/015/page12.html
index 81528f63c79..99d3959582d 100644
--- a/docs/tutorials/015/page12.html
+++ b/docs/tutorials/015/page12.html
@@ -19,7 +19,6 @@ set of protocol objects that will manipulate the data. Our primary
concern in this file is to get everything in the correct order!
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>PROTOCOL_TASK_H</font>
@@ -37,62 +36,59 @@ concern in this file is to get everything in the correct order!
class Protocol_Task : public ACE_Task&lt;ACE_MT_SYNCH>
{
public:
+ typedef ACE_Task&lt;ACE_MT_SYNCH> inherited;
- typedef ACE_Task&lt;ACE_MT_SYNCH> inherited;
-
- <font color=red>// A choice of concurrency strategies is offered by the</font>
- <font color=red>// constructor. In most cases it makes sense to set this to</font>
- <font color=red>// zero and let things proceed serially. You might have a</font>
- <font color=red>// need, however, for some of your tasks to have their own thread.</font>
- Protocol_Task( int _thr_count );
+ <font color=red>// A choice of concurrency strategies is offered by the constructor.</font>
+ <font color=red>// In most cases it makes sense to set this to zero and let things</font>
+ <font color=red>// proceed serially. You might have a need, however, for some of</font>
+ <font color=red>// your tasks to have their own thread.</font>
+ Protocol_Task (int thr_count);
- ~Protocol_Task(void);
+ ~Protocol_Task (void);
- <font color=red>// open() is invoked when the task is inserted into the stream.</font>
- virtual int open(void *arg);
+ <font color=red>// open() is invoked when the task is inserted into the stream.</font>
+ virtual int open (void *arg);
- <font color=red>// close() is invoked when the stream is closed (flags will be</font>
- <font color=red>// set to '1') and when the svc() method exits (flags will be</font>
- <font color=red>// '0').</font>
- virtual int close(u_long flags);
+ <font color=red>// close() is invoked when the stream is closed (flags will be set</font>
+ <font color=red>// to '1') and when the svc() method exits (flags will be '0').</font>
+ virtual int close (u_long flags);
- <font color=red>// As data travels through the stream, the put() method of</font>
- <font color=red>// each task is invoked to keep the data moving along.</font>
- virtual int put(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
+ <font color=red>// As data travels through the stream, the put() method of each task</font>
+ <font color=red>// is invoked to keep the data moving along.</font>
+ virtual int put (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
- <font color=red>// If you choose to activate the task then this method will be</font>
- <font color=red>// doing all of the work.</font>
- virtual int svc(void);
+ <font color=red>// If you choose to activate the task then this method will be doing</font>
+ <font color=red>// all of the work.</font>
+ virtual int svc (void);
protected:
- <font color=red>// Called by put() or svc() as necessary to process a block of</font>
- <font color=red>// data.</font>
- int process(ACE_Message_Block * message, ACE_Time_Value *timeout);
+ <font color=red>// Called by put() or svc() as necessary to process a block of data.</font>
+ int process (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
- <font color=red>// Just let us know if we're active or not.</font>
- int is_active(void)
- {
- return this->thr_count() != 0;
- }
+ <font color=red>// Just let us know if we're active or not.</font>
+ int is_active (void)
+ {
+ return this->thr_count () != 0;
+ }
- <font color=red>// Tasks on the writter (downstream) side of the stream</font>
- <font color=red>// are called upon to send() data that will ultimately go to</font>
- <font color=red>// the peer.</font>
- virtual int send(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
+ <font color=red>// Tasks on the writter (downstream) side of the stream are called</font>
+ <font color=red>// upon to send() data that will ultimately go to the peer.</font>
+ virtual int send (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
- <font color=red>// Tasks on the reader (upstream) side will be receiving data</font>
- <font color=red>// that came from the peer.</font>
- virtual int recv(ACE_Message_Block * message,
- ACE_Time_Value *timeout);
+ <font color=red>// Tasks on the reader (upstream) side will be receiving data that</font>
+ <font color=red>// came from the peer.</font>
+ virtual int recv (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
private:
- int desired_thr_count_;
+ int desired_thr_count_;
};
-<font color=blue>#endif</font> <font color=red>// PROTOCOL_TASK_H</font>
+<font color=blue>#endif</font> <font color=red>/* PROTOCOL_TASK_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page13.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page14.html b/docs/tutorials/015/page14.html
index 1624577470e..ea27af4db50 100644
--- a/docs/tutorials/015/page14.html
+++ b/docs/tutorials/015/page14.html
@@ -12,24 +12,17 @@
<P>
<HR WIDTH="100%">
-The implementation of Xmit isn't too complicated. If we choose to
-combine it with the Recv task we simply lift the recv() method from
-that object and drop it into this one.
+The Xmit object knows how to send data to the peer. It sits at the
+tail of the stream and gets everything that flows down from the head.
+In keeping with the spirit of things, this object does only one thing
+and doesn't concern itself with anyone else' details.
<P>
-Note that close() must decide if it's being called when the stream is
-shutdown or when it's svc() method exits. Since we tell the baseclass
-not to use any threads it's a safe bet that flags will always be
-non-zero. Still, it's good practice to plan for the future by
-checking the value.
-<P>
-Note also that when we send the data we prefix it with the data size.
-This let's our sibling Recv ensure that an entire block is received
-together. This can be very important for compression and encryption
-processes which typically work better with blocks of data instead of
-streams of data.
+The only thing you might want to do is combine it with Recv. Why?
+As you'll realize in a page or two, the Xmit and Recv objects must
+interact if you're going to ensure a safe transit. By having a single
+object it's easier to coordinate and maintain the interaction.
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>XMIT_H</font>
@@ -46,38 +39,36 @@ class ACE_SOCK_Stream;
class Xmit : public Protocol_Task
{
public:
+ typedef Protocol_Task inherited;
- typedef Protocol_Task inherited;
-
- <font color=red>// We must be given a valid peer when constructed. Without that</font>
- <font color=red>// we don't know who to send data to.</font>
- Xmit( ACE_SOCK_Stream & _peer );
-
- ~Xmit(void);
+ <font color=red>// We must be given a valid peer when constructed. Without that we</font>
+ <font color=red>// don't know who to send data to.</font>
+ Xmit (ACE_SOCK_Stream &peer);
+ ~Xmit (void);
- <font color=red>// As you know, close() will be called in a couple of ways by the</font>
- <font color=red>// ACE framework. We use that opportunity to terminate the</font>
- <font color=red>// connection to the peer.</font>
- int close(u_long flags);
+ <font color=red>// As you know, close() will be called in a couple of ways by the</font>
+ <font color=red>// ACE framework. We use that opportunity to terminate the</font>
+ <font color=red>// connection to the peer.</font>
+ int close (u_long flags);
protected:
- ACE_SOCK_Stream & peer(void)
- {
- return this->peer_;
- }
+ ACE_SOCK_Stream &peer (void)
+ {
+ return this->peer_;
+ }
- <font color=red>// Send the data to the peer. By now it will have been</font>
- <font color=red>// completely protocol-ized by other tasks in the stream.</font>
- int send(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
+ <font color=red>// Send the data to the peer. By now it will have been completely</font>
+ <font color=red>// protocol-ized by other tasks in the stream.</font>
+ int send (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
private:
- <font color=red>// A representation of the peer we're talking to.</font>
- ACE_SOCK_Stream & peer_;
+ <font color=red>// A representation of the peer we're talking to.</font>
+ ACE_SOCK_Stream &peer_;
};
-<font color=blue>#endif</font> <font color=red>// XMIT_H</font>
+<font color=blue>#endif</font> <font color=red>/* XMIT_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page15.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page15.html b/docs/tutorials/015/page15.html
index be4d3e464a0..d186b712daf 100644
--- a/docs/tutorials/015/page15.html
+++ b/docs/tutorials/015/page15.html
@@ -12,18 +12,21 @@
<P>
<HR WIDTH="100%">
-Recv is the sibling to Xmit. Again, they could be combined into a
-single object if you want.
+The implementation of Xmit isn't too complicated. If we choose to
+combine it with the Recv task we simply lift the recv() method from
+that object and drop it into this one.
<P>
-An ACE_Stream is designed to handle downstream traffic very
-well. You put() data into it and it flows along towards the tail.
-However, there doesn't seem to be a way to put data in such that it
-will travel upstream. To get around that, I've added a get() method
-to Recv that will trigger a read on the socket. Recv will then put
-the data to the next upstream module and we're on our way. As noted
-earlier, that data will eventually show up either in the <i>reader</i>
-(if installed on the stream open()) or the stream head reader task's
-message queue.
+Note that close() must decide if it's being called when the stream is
+shutdown or when it's svc() method exits. Since we tell the baseclass
+not to use any threads it's a safe bet that flags will always be
+non-zero. Still, it's good practice to plan for the future by
+checking the value.
+<P>
+Note also that when we send the data we prefix it with the data size.
+This let's our sibling Recv ensure that an entire block is received
+together. This can be very important for compression and encryption
+processes which typically work better with blocks of data instead of
+streams of data.
<HR>
<PRE>
diff --git a/docs/tutorials/015/page16.html b/docs/tutorials/015/page16.html
index aa57e8fb2da..e372f6d68bf 100644
--- a/docs/tutorials/015/page16.html
+++ b/docs/tutorials/015/page16.html
@@ -12,13 +12,20 @@
<P>
<HR WIDTH="100%">
-The Recv implementation is nearly as simple as Xmit. There's
-opportunity for error when we get the message size and we have to
-manage the lifetime of the tickler but other than that it's pretty
-basic stuff.
+Recv is the sibling to Xmit. Again, they could be combined into a
+single object if you want.
+<P>
+An ACE_Stream is designed to handle downstream traffic very
+well. You put() data into it and it flows along towards the tail.
+However, there doesn't seem to be a way to put data in such that it
+will travel upstream. To get around that, I've added a get() method
+to Recv that will trigger a read on the socket. Recv will then put
+the data to the next upstream module and we're on our way. As noted
+earlier, that data will eventually show up either in the <i>reader</i>
+(if installed on the stream open()) or the stream head reader task's
+message queue.
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>RECV_H</font>
@@ -34,52 +41,49 @@ class ACE_SOCK_Stream;
class Recv : public Protocol_Task
{
public:
+ typedef Protocol_Task inherited;
- typedef Protocol_Task inherited;
-
- <font color=red>// Give it someone to talk to...</font>
- Recv( ACE_SOCK_Stream & _peer );
-
- ~Recv(void);
+ <font color=red>// Give it someone to talk to...</font>
+ Recv (ACE_SOCK_Stream &peer);
+ ~Recv (void);
- <font color=red>// Trigger a read from the socket</font>
- int get(void);
+ <font color=red>// Trigger a read from the socket</font>
+ int get (void);
- <font color=red>// In some cases it might be easier to check the "<font color=green>state</font>" of the</font>
- <font color=red>// Recv object than to rely on return codes filtering back to</font>
- <font color=red>// you.</font>
- int error(void)
- {
- return this->error_;
- }
+ <font color=red>// In some cases it might be easier to check the "<font color=green>state</font>" of the Recv</font>
+ <font color=red>// object than to rely on return codes filtering back to you.</font>
+ int error (void)
+ {
+ return this->error_;
+ }
protected:
- ACE_SOCK_Stream & peer(void)
- {
- return this->peer_;
- }
+ ACE_SOCK_Stream &peer (void)
+ {
+ return this->peer_;
+ }
- <font color=red>// The baseclass will trigger this when our get() method is</font>
- <font color=red>// called. A message block of the appropriate size is created,</font>
- <font color=red>// filled and passed up the stream.</font>
- int recv(ACE_Message_Block * message,
- ACE_Time_Value *timeout = 0);
+ <font color=red>// The baseclass will trigger this when our get() method is called.</font>
+ <font color=red>// A message block of the appropriate size is created, filled and</font>
+ <font color=red>// passed up the stream.</font>
+ int recv (ACE_Message_Block *message,
+ ACE_Time_Value *timeout = 0);
private:
- <font color=red>// Our endpoint</font>
- ACE_SOCK_Stream & peer_;
+ <font color=red>// Our endpoint</font>
+ ACE_SOCK_Stream &peer_;
- <font color=red>// get() uses a bogus message block to cause the baseclass to</font>
- <font color=red>// invoke recv(). To avoid memory thrashing, we create that</font>
- <font color=red>// bogus message once and reuse it for the life of Recv.</font>
- ACE_Message_Block * tickler_;
+ <font color=red>// get() uses a bogus message block to cause the baseclass to invoke</font>
+ <font color=red>// recv(). To avoid memory thrashing, we create that bogus message</font>
+ <font color=red>// once and reuse it for the life of Recv.</font>
+ ACE_Message_Block *tickler_;
- <font color=red>// Our error flag (duh)</font>
- int error_;
+ <font color=red>// Our error flag (duh)</font>
+ int error_;
};
-<font color=blue>#endif</font> <font color=red>// RECV_H</font>
+<font color=blue>#endif</font> <font color=red>/* RECV_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page17.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page17.html b/docs/tutorials/015/page17.html
index 8d3aaf660d0..de868086604 100644
--- a/docs/tutorials/015/page17.html
+++ b/docs/tutorials/015/page17.html
@@ -12,8 +12,10 @@
<P>
<HR WIDTH="100%">
-This and the next three pages present the protocol objects that
-provide compression and encryption. If you were hoping to
+The Recv implementation is nearly as simple as Xmit. There's
+opportunity for error when we get the message size and we have to
+manage the lifetime of the tickler but other than that it's pretty
+basic stuff.
<HR>
<PRE>
diff --git a/docs/tutorials/015/page18.html b/docs/tutorials/015/page18.html
index ef67934b597..c19a1559750 100644
--- a/docs/tutorials/015/page18.html
+++ b/docs/tutorials/015/page18.html
@@ -20,7 +20,6 @@ stuff though and if anyone wants to integrate one of them into the
tutorial I'll be glad to take it!
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>COMPRESSOR_H</font>
@@ -35,34 +34,34 @@ class Compressor : public Protocol_Task
{
public:
- typedef Protocol_Task inherited;
+ typedef Protocol_Task inherited;
- <font color=red>// I've given you the option of creating this task derivative</font>
- <font color=red>// with a number of threads. In retro-spect that really isn't</font>
- <font color=red>// a good idea. Most client/server systems rely on requests</font>
- <font color=red>// and responses happening in a predicatable order. Introduce</font>
- <font color=red>// a thread pool and message queue and that ordering goes</font>
- <font color=red>// right out the window. In other words: Don't ever use the</font>
- <font color=red>// constructor parameter!</font>
- Compressor( int _thr_count = 0 );
+ <font color=red>// I've given you the option of creating this task derivative</font>
+ <font color=red>// with a number of threads. In retro-spect that really isn't</font>
+ <font color=red>// a good idea. Most client/server systems rely on requests</font>
+ <font color=red>// and responses happening in a predicatable order. Introduce</font>
+ <font color=red>// a thread pool and message queue and that ordering goes</font>
+ <font color=red>// right out the window. In other words: Don't ever use the</font>
+ <font color=red>// constructor parameter!</font>
+ Compressor (int thr_count = 0);
- ~Compressor(void);
+ ~Compressor (void);
protected:
- <font color=red>// This is called when the compressor is on the downstream</font>
- <font color=red>// side. We'll take the message, compress it and move it</font>
- <font color=red>// along to the next module.</font>
- int send(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
+ <font color=red>// This is called when the compressor is on the downstream side.</font>
+ <font color=red>// We'll take the message, compress it and move it along to the next</font>
+ <font color=red>// module.</font>
+ int send (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
- <font color=red>// This one is called on the upstream side. No surprise: we</font>
- <font color=red>// decompress the data and send it on up the stream.</font>
- int recv(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
+ <font color=red>// This one is called on the upstream side. No surprise: we</font>
+ <font color=red>// decompress the data and send it on up the stream.</font>
+ int recv (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
};
-<font color=blue>#endif</font> <font color=red>// COMPRESSOR_H</font>
+<font color=blue>#endif</font> <font color=red>/* COMPRESSOR_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page19.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/015/page20.html b/docs/tutorials/015/page20.html
index 641399cb4e2..6b8917150e7 100644
--- a/docs/tutorials/015/page20.html
+++ b/docs/tutorials/015/page20.html
@@ -21,7 +21,6 @@ show you the hooks and entry points and let someone else contribute an
encryptor.
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CRYPT_H</font>
@@ -36,26 +35,26 @@ class Crypt : public Protocol_Task
{
public:
- typedef Protocol_Task inherited;
+ typedef Protocol_Task inherited;
- <font color=red>// Again we have the option of multiple threads and again I</font>
- <font color=red>// regret tempting folks to use it.</font>
- Crypt( int _thr_count = 0 );
+ <font color=red>// Again we have the option of multiple threads and again I</font>
+ <font color=red>// regret tempting folks to use it.</font>
+ Crypt (int thr_count = 0);
- ~Crypt(void);
+ ~Crypt (void);
protected:
- <font color=red>// Moving downstream will encrypt the data</font>
- int send(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
+ <font color=red>// Moving downstream will encrypt the data</font>
+ int send (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
- <font color=red>// And moving upstream will decrypt it.</font>
- int recv(ACE_Message_Block *message,
- ACE_Time_Value *timeout);
+ <font color=red>// And moving upstream will decrypt it.</font>
+ int recv (ACE_Message_Block *message,
+ ACE_Time_Value *timeout);
};
-<font color=blue>#endif</font> <font color=red>// CRYPT_H</font>
+<font color=blue>#endif</font> <font color=red>/* CRYPT_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page21.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/016/page02.html b/docs/tutorials/016/page02.html
index fdcfc4e8c1b..70e58f57e3f 100644
--- a/docs/tutorials/016/page02.html
+++ b/docs/tutorials/016/page02.html
@@ -56,8 +56,8 @@ To help out with that, I've created the class below to encapsulate the
three elements necessary for the condition to work. I've then added
methods for manipulation of the condition variable and waiting for the
condition to occur.
-<HR><PRE>
-
+<HR>
+<PRE>
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>CONDITION_H</font>
@@ -65,157 +65,153 @@ condition to occur.
<font color=blue>#include</font> "<font color=green>ace/Synch.h</font>"
-<font color=red>/** A wrapper for ACE_Condition&lt;>.
- When you're using an ACE_Condition&lt;> you have to have three things:
- - Some variable that embodies the condition you're looking for
- - A mutex to prevent simultaneous access to that variable from different threads
- - An ACE_Condition&lt;> that enables blocking on state changes in the variable
- The class I create here will contain those three things. For the
- actual condition variable I've chosen an integer. You could
- easily turn this clas into a template parameterized on the
- condition variable's data type if 'int' isn't what you want.
- */</font>
+<font color=red>/** A wrapper for ACE_Condition&lt;>. When you're using an
+ ACE_Condition&lt;> you have to have three things: - Some variable
+ that embodies the condition you're looking for - A mutex to
+ prevent simultaneous access to that variable from different
+ threads - An ACE_Condition&lt;> that enables blocking on state
+ changes in the variable The class I create here will contain those
+ three things. For the actual condition variable I've chosen an
+ integer. You could easily turn this clas into a template
+ parameterized on the condition variable's data type if 'int' isn't
+ what you want. */</font>
class Condition
{
public:
- <font color=red>// From here on I'll use value_t instead of 'int' to make any</font>
- <font color=red>// future upgrades easier.</font>
- typedef int value_t;
+ <font color=red>// From here on I'll use value_t instead of 'int' to make any</font>
+ <font color=red>// future upgrades easier.</font>
+ typedef int value_t;
- <font color=red>// Initialize the condition variable</font>
- Condition(value_t _value = 0);
- ~Condition(void);
-
- <font color=red>/* I've created a number of arithmetic operators on the class
- that pass their operation on to the variable. If you turn
- this into a template then some of these may not be
- appropriate...
- For the ones that take a parameter, I've stuck with 'int'
- instead of 'value_t' to reinforce the fact that you'll need
- a close look at these if you choose to change the 'value_t'
- typedef.
- */</font>
-
- <font color=red>// Increment & decrement</font>
- Condition & operator++(void);
- Condition & operator--(void);
-
- <font color=red>// Increase & decrease</font>
- Condition & operator+=(int _inc);
- Condition & operator-=(int _inc);
-
- <font color=red>// Just to be complete</font>
- Condition & operator*=(int _inc);
- Condition & operator/=(int _inc);
- Condition & operator%=(int _inc);
-
- <font color=red>// Set/Reset the condition variable's value</font>
- Condition & operator=( value_t _value );
-
- <font color=red>/* These four operators perform the actual waiting. For
- instance:
-
- operator!=(int _value)
-
- is implemented as:
-
- Guard guard(mutex_)
- while( value_ != _value )
- condition_.wait();
-
- This is the "<font color=green>typical</font>" use for condition mutexes. Each of
- the operators below behaves this way for their respective
- comparisions.
-
- To use one of these in code, you would simply do:
-
- Condition mycondition;
- ...
- <font color=red>// Wait until the condition variable has the value 42</font>
- mycondition != 42
- ...
- */</font>
-
- <font color=red>// As long as the condition variable is NOT EQUAL TO _value, we wait</font>
- int operator!=( value_t _value );
- <font color=red>// As long as the condition variable is EXACTLY EQUAL TO _value, we wait</font>
- int operator==( value_t _value );
- <font color=red>// As long as the condition variable is LESS THAN OR EQUAL TO _value, we wait</font>
- int operator&lt;=( value_t _value );
- <font color=red>// As long as the condition variable is GREATER THAN OR EQUAL TO _value, we wait</font>
- int operator>=( value_t _value );
-
- <font color=red>// Return the value of the condition variable</font>
- operator value_t (void);
-
- <font color=red>/* In addition to the four ways of waiting above, I've also
- create a method that will invoke a function object for each
- iteration of the while() loop.
- Derive yourself an object from <font color=#008888>Condition::Compare</font> and
- overload operator()(value_t) to take advantage of this. Have
- the function return non-zero when you consider the condition
- to be met.
- */</font>
- class Compare
- {
- public:
- virtual int operator() ( value_t _value ) = 0;
- };
-
- <font color=red>/* Wait on the condition until _compare(value) returns
- non-zero. This is a little odd since we're not really testing
- equality. Just be sure that _compare(value_) will return
- non-zero when you consider the condition to be met.
- */</font>
- int operator==( Compare & _compare );
+ <font color=red>// Initialize the condition variable</font>
+ Condition (value_t value = 0);
+ ~Condition (void);
+
+ <font color=red>/* I've created a number of arithmetic operators on the class that
+ pass their operation on to the variable. If you turn this into a
+ template then some of these may not be appropriate... For the
+ ones that take a parameter, I've stuck with 'int' instead of
+ 'value_t' to reinforce the fact that you'll need a close look at
+ these if you choose to change the 'value_t' typedef. */</font>
+
+ <font color=red>// Increment & decrement</font>
+ Condition &operator++ (void);
+ Condition &operator-- (void);
+
+ <font color=red>// Increase & decrease</font>
+ Condition &operator+= (int inc);
+ Condition &operator-= (int inc);
+
+ <font color=red>// Just to be complete</font>
+ Condition &operator*= (int inc);
+ Condition &operator/= (int inc);
+ Condition &operator%= (int inc);
+
+ <font color=red>// Set/Reset the condition variable's value</font>
+ Condition &operator= (value_t value);
+
+ <font color=red>/* These four operators perform the actual waiting. For instance:
+
+ operator!=(int _value)
+
+ is implemented as:
+
+ Guard guard(mutex_)
+ while( value_ != _value )
+ condition_.wait();
+
+ This is the "<font color=green>typical</font>" use for condition mutexes. Each of the
+ operators below behaves this way for their respective
+ comparisions.
+
+ To use one of these in code, you would simply do:
+
+ Condition mycondition;
+ ...
+ <font color=red>// Wait until the condition variable has the value 42</font>
+ mycondition != 42
+ ... */</font>
+
+ <font color=red>// As long as the condition variable is NOT EQUAL TO &lt;value>, we wait</font>
+ int operator!= (value_t value);
+
+ <font color=red>// As long as the condition variable is EXACTLY EQUAL TO &lt;value>, we</font>
+ <font color=red>// wait</font>
+ int operator== (value_t value);
+
+ <font color=red>// As long as the condition variable is LESS THAN OR EQUAL TO</font>
+ <font color=red>// &lt;value>, we wait</font>
+ int operator&lt;= (value_t value);
+
+ <font color=red>// As long as the condition variable is GREATER THAN OR EQUAL TO</font>
+ <font color=red>// &lt;value>, we wait</font>
+ int operator>= (value_t value);
+
+ <font color=red>// Return the value of the condition variable</font>
+ operator value_t (void);
+
+ <font color=red>/* In addition to the four ways of waiting above, I've also create a
+ method that will invoke a function object for each iteration of
+ the while() loop. Derive yourself an object from
+ <font color=#008888>Condition::Compare</font> and overload operator()(value_t) to take
+ advantage of this. Have the function return non-zero when you
+ consider the condition to be met. */</font>
+ class Compare
+ {
+ public:
+ virtual int operator() (value_t value) = 0;
+ };
+
+ <font color=red>/* Wait on the condition until _compare(value) returns non-zero.
+ This is a little odd since we're not really testing equality.
+ Just be sure that _compare(value_) will return non-zero when you
+ consider the condition to be met. */</font>
+ int operator== (Compare & compare);
private:
- <font color=red>// Prevent copy construction and assignment.</font>
- Condition( const Condition & _condition );
- Condition & operator= ( const Condition & _condition );
-
- <font color=red>/* Typedefs make things easier to change later.
- ACE_Condition_Thread_Mutex is used as a shorthand for
- ACE_Condition&lt;ACE_Thread_Mutex> and also because it may
- provide optimizations we can use.
- */</font>
- typedef ACE_Thread_Mutex mutex_t;
- typedef ACE_Condition_Thread_Mutex condition_t;
- typedef ACE_Guard&lt;mutex_t> guard_t;
-
- <font color=red>// The mutex that keeps the data save</font>
- mutex_t mutex_;
-
- <font color=red>// The condition mutex that makes waiting on the condition</font>
- <font color=red>// easier.</font>
- condition_t * condition_;
-
- <font color=red>// The acutal variable that embodies the condition we're</font>
- <font color=red>// waiting for.</font>
- value_t value_;
-
- <font color=red>// Accessors for the two mutexes.</font>
- mutex_t & mutex(void)
- {
- return this->mutex_;
- }
-
- condition_t & condition(void)
- {
- return *(this->condition_);
- }
-
- <font color=red>// This particular accessor will make things much easier if we </font>
- <font color=red>// decide that 'int' isn't the correct datatype for value_.</font>
- <font color=red>// Note that we keep this private and force clients of the class</font>
- <font color=red>// to use the cast operator to get a copy of the value.</font>
- value_t & value(void)
- {
- return this->value_;
- }
+ <font color=red>// Prevent copy construction and assignment.</font>
+ Condition (const Condition &condition);
+ Condition &operator= (const Condition &condition);
+
+ <font color=red>/* Typedefs make things easier to change later.
+ ACE_Condition_Thread_Mutex is used as a shorthand for
+ ACE_Condition&lt;ACE_Thread_Mutex> and also because it may provide
+ optimizations we can use. */</font>
+ typedef ACE_Thread_Mutex mutex_t;
+ typedef ACE_Condition_Thread_Mutex condition_t;
+ typedef ACE_Guard&lt;mutex_t> guard_t;
+
+ <font color=red>// The mutex that keeps the data save</font>
+ mutex_t mutex_;
+
+ <font color=red>// The condition mutex that makes waiting on the condition easier.</font>
+ condition_t *condition_;
+
+ <font color=red>// The acutal variable that embodies the condition we're waiting</font>
+ <font color=red>// for.</font>
+ value_t value_;
+
+ <font color=red>// Accessors for the two mutexes.</font>
+ mutex_t &mutex (void)
+ {
+ return this->mutex_;
+ }
+
+ condition_t &condition (void)
+ {
+ return *this->condition_;
+ }
+
+ <font color=red>// This particular accessor will make things much easier if we</font>
+ <font color=red>// decide that 'int' isn't the correct datatype for value_. Note</font>
+ <font color=red>// that we keep this private and force clients of the class to use</font>
+ <font color=red>// the cast operator to get a copy of the value.</font>
+ value_t &value (void)
+ {
+ return this->value_;
+ }
};
-<font color=blue>#endif</font> <font color=red>// CONDITION_H</font>
+<font color=blue>#endif</font> <font color=red>/* CONDITION_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/016/page03.html b/docs/tutorials/016/page03.html
index 43e65f5001b..4c4077a415a 100644
--- a/docs/tutorials/016/page03.html
+++ b/docs/tutorials/016/page03.html
@@ -45,7 +45,7 @@ include the mess I've got below!
to clients of the class. It also allows us to use a private method
for getting a reference to the value when we need to modify it.
*/</font>
-<font color=#008888>Condition::operator</font> value_t (void)
+<font color=#008888>Condition::operator</font> Condition::value_t (void)
{
<font color=red>// Place a guard around the variable so that it won't change as</font>
<font color=red>// we're copying it back to the client.</font>
diff --git a/docs/tutorials/016/page04.html b/docs/tutorials/016/page04.html
index 75c953961cc..b94fe2e48af 100644
--- a/docs/tutorials/016/page04.html
+++ b/docs/tutorials/016/page04.html
@@ -17,7 +17,8 @@ derivative that will serve as a baseclass for other objects that test
specific functions of the Condition class. Notice how easy it is to
integrate a Condition into the application without keeping track of
three related member variables.
-<HR><PRE>
+<HR>
+<PRE>
<font color=red>// $Id$</font>
diff --git a/docs/tutorials/016/page05.html b/docs/tutorials/016/page05.html
index c8aeb988a5e..baf3eb23a4a 100644
--- a/docs/tutorials/016/page05.html
+++ b/docs/tutorials/016/page05.html
@@ -26,5 +26,6 @@ create a more useful class for your application.
<LI><A HREF="Condition_i.cpp">Condition_i.cpp</A>
<LI><A HREF="condition.cpp">condition.cpp</A>
<LI><A HREF="Makefile">Makefile</A>
-</UL><P><HR WIDTH="100%">
+</UL>
+<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER>
diff --git a/docs/tutorials/017/page03.html b/docs/tutorials/017/page03.html
index 6da527bbdb8..904fc58701f 100644
--- a/docs/tutorials/017/page03.html
+++ b/docs/tutorials/017/page03.html
@@ -26,7 +26,6 @@ wait() as a now-protected method. The result would allow you to treat
the Barrier object almost as a "synchronization guard".
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>BARRIER_H</font>
@@ -42,49 +41,48 @@ the Barrier object almost as a "synchronization guard".
class Barrier
{
public:
- <font color=red>// Basic constructor and destructor. If you only need to</font>
- <font color=red>// synch the start of your threads, you can safely delete your </font>
- <font color=red>// Barrier object after invoking done(). Of course, you</font>
- <font color=red>// should be careful to only delete the object once!</font>
- Barrier(void);
- ~Barrier(void);
+ <font color=red>// Basic constructor and destructor. If you only need to synch the</font>
+ <font color=red>// start of your threads, you can safely delete your Barrier object</font>
+ <font color=red>// after invoking done(). Of course, you should be careful to only</font>
+ <font color=red>// delete the object once!</font>
+ Barrier (void);
+ ~Barrier (void);
- <font color=red>// Set and get the number of threads that the barrier will</font>
- <font color=red>// manage. If you add or remove threads to your application</font>
- <font color=red>// at run-time you can use the mutator to reflect that</font>
- <font color=red>// change. Note, however, that you can only do that from the</font>
- <font color=red>// thread which first created the Barrier. (This is a</font>
- <font color=red>// limitation of my Barrier object, not the ACE_Barrier.)</font>
- <font color=red>// The optional _wait parameter will cause wait() to be</font>
- <font color=red>// invoked if there is already a valid threads value.</font>
- int threads( u_int _threads, int _wait = 0);
- u_int threads(void);
+ <font color=red>// Set and get the number of threads that the barrier will manage.</font>
+ <font color=red>// If you add or remove threads to your application at run-time you</font>
+ <font color=red>// can use the mutator to reflect that change. Note, however, that</font>
+ <font color=red>// you can only do that from the thread which first created the</font>
+ <font color=red>// Barrier. (This is a limitation of my Barrier object, not the</font>
+ <font color=red>// ACE_Barrier.) The optional _wait parameter will cause wait() to</font>
+ <font color=red>// be invoked if there is already a valid threads value.</font>
+ int threads (u_int threads, int wait = 0);
+ u_int threads (void);
- <font color=red>// Wait for all threads to reach the point where this is</font>
- <font color=red>// invoked. Because of the snappy way in which ACE_Barrier is </font>
- <font color=red>// implemented, you can invoke these back-to-back with no ill-effects.</font>
- int wait(void);
+ <font color=red>// Wait for all threads to reach the point where this is invoked.</font>
+ <font color=red>// Because of the snappy way in which ACE_Barrier is implemented,</font>
+ <font color=red>// you can invoke these back-to-back with no ill-effects.</font>
+ int wait (void);
- <font color=red>// done() will invoke wait(). Before returning though, it</font>
- <font color=red>// will delete the barrier_ pointer below to reclaim some memory.</font>
- int done(void);
+ <font color=red>// done() will invoke wait(). Before returning though, it will</font>
+ <font color=red>// delete the barrier_ pointer below to reclaim some memory.</font>
+ int done (void);
protected:
- <font color=red>// The number of threads we're synching</font>
- ACE_Atomic_Op&lt;ACE_Mutex,u_int> threads_;
+ <font color=red>// The number of threads we're synching</font>
+ ACE_Atomic_Op&lt;ACE_Mutex,u_int> threads_;
- <font color=red>// The ACE_Barrier that does all of the work</font>
- ACE_Barrier * barrier_;
+ <font color=red>// The ACE_Barrier that does all of the work</font>
+ ACE_Barrier *barrier_;
- <font color=red>// The thread which created the Barrier in the first place.</font>
- <font color=red>// Only this thread can change the threads_ value.</font>
- ACE_thread_t owner_;
+ <font color=red>// The thread which created the Barrier in the first place. Only</font>
+ <font color=red>// this thread can change the threads_ value.</font>
+ ACE_thread_t owner_;
- <font color=red>// An internal method that constructs the barrier_ as needed.</font>
- int make_barrier( int _wait );
+ <font color=red>// An internal method that constructs the barrier_ as needed.</font>
+ int make_barrier (int wait);
};
-<font color=blue>#endif</font> <font color=red>// BARRIER_H</font>
+<font color=blue>#endif</font> <font color=red>/* BARRIER_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/018/page03.html b/docs/tutorials/018/page03.html
index e94b8b9c844..5eccee967ae 100644
--- a/docs/tutorials/018/page03.html
+++ b/docs/tutorials/018/page03.html
@@ -38,7 +38,6 @@ inclusion. If you've already got them broken out then you'll save
yourself a lot of time!
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>TEST_T_H</font>
@@ -55,49 +54,52 @@ yourself a lot of time!
templated class. Generally, there is a non-templated class defined
also such as foobar.h that would be included instead of foobar_T.h.
*/</font>
+
template &lt;class MUTEX>
class Test_T : public ACE_Task&lt;ACE_MT_SYNCH>
{
public:
- <font color=red>// Allow our derivative to name the class so that we can tell</font>
- <font color=red>// the user what's going on as we test the lock.</font>
- Test_T( const char * _name );
-
- <font color=red>// This will run the entire test. open() will be called to</font>
- <font color=red>// activate the task's threads. We then add a number of</font>
- <font color=red>// messages to the queue for svc() to process.</font>
- int run(void);
+ <font color=red>// Allow our derivative to name the class so that we can tell the</font>
+ <font color=red>// user what's going on as we test the lock.</font>
+ Test_T (const char *name);
+
+ <font color=red>// This will run the entire test. open() will be called to activate</font>
+ <font color=red>// the task's threads. We then add a number of messages to the</font>
+ <font color=red>// queue for svc() to process.</font>
+ int run (void);
protected:
- <font color=red>// Activate a few threads</font>
- int open( void * _arg = 0 );
- <font color=red>// Read some things from the message queue and exercise the</font>
- <font color=red>// lock.</font>
- int svc( void );
- <font color=red>// Send a message block to svc(). If _message is 0 then send</font>
- <font color=red>// a shutdown request (e.g., MB_HANGUP)</font>
- int send( ACE_Message_Block * _message = 0 );
-
- <font color=red>// The object's name. Typically provided by a derivative.</font>
- const char * name_;
- <font color=red>// We want to barrier the svc() methods to give all of the</font>
- <font color=red>// threads a fair chance</font>
- ACE_Barrier barrier_;
-
- <font color=red>// As each thread enters svc() it will increment this. While</font>
- <font color=red>// we have a thread id available to us, I wanted a simple</font>
- <font color=red>// value to display in debug messages.</font>
- ACE_Atomic_Op&lt;ACE_Mutex,int> thread_num_;
-
- <font color=red>// Set our mutex type based on the template parameter. We</font>
- <font color=red>// then build a guard type based on that type.</font>
- typedef MUTEX mutex_t;
- typedef ACE_Guard&lt;mutex_t> guard_t;
-
- <font color=red>// Our mutex. We'll use this in svc() to protect imaginary</font>
- <font color=red>// shared resources.</font>
- mutex_t mutex_;
+ <font color=red>// Activate a few threads</font>
+ int open (void *arg = 0);
+
+ <font color=red>// Read some things from the message queue and exercise the lock.</font>
+ int svc (void);
+
+ <font color=red>// Send a message block to svc(). If _message is 0 then send a</font>
+ <font color=red>// shutdown request (e.g., MB_HANGUP)</font>
+ int send (ACE_Message_Block * message = 0);
+
+ <font color=red>// The object's name. Typically provided by a derivative.</font>
+ const char *name_;
+
+ <font color=red>// We want to barrier the svc() methods to give all of the threads a</font>
+ <font color=red>// fair chance</font>
+ ACE_Barrier barrier_;
+
+ <font color=red>// As each thread enters svc() it will increment this. While we</font>
+ <font color=red>// have a thread id available to us, I wanted a simple value to</font>
+ <font color=red>// display in debug messages.</font>
+ ACE_Atomic_Op&lt;ACE_Mutex,int> thread_num_;
+
+ <font color=red>// Set our mutex type based on the template parameter. We then</font>
+ <font color=red>// build a guard type based on that type.</font>
+ typedef MUTEX mutex_t;
+ typedef ACE_Guard&lt;mutex_t> guard_t;
+
+ <font color=red>// Our mutex. We'll use this in svc() to protect imaginary shared</font>
+ <font color=red>// resources.</font>
+ mutex_t mutex_;
};
<font color=red>/* Although different compilers differ in their details, almost all of
@@ -115,7 +117,7 @@ protected:
<font color=blue>#pragma</font> <font color=purple>implementation</font> ("<font color=green>Test_T.cpp</font>")
<font color=blue>#endif</font> <font color=red>/* ACE_TEMPLATES_REQUIRE_PRAGMA */</font>
-<font color=blue>#endif</font> <font color=red>// TEST_T_H</font>
+<font color=blue>#endif</font> <font color=red>/* TEST_T_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/018/page04.html b/docs/tutorials/018/page04.html
index dcf0ac3ca2b..639732eb7e8 100644
--- a/docs/tutorials/018/page04.html
+++ b/docs/tutorials/018/page04.html
@@ -26,7 +26,6 @@ differently. In a real app, you'd be doing this to protect shared
resources that the threads might clobber.
<HR>
<PRE>
-
<font color=red>// $Id$</font>
<font color=red>/* This is something new... Since we're included by the header, we
@@ -48,175 +47,177 @@ resources that the threads might clobber.
creation to make the output more readable.
*/</font>
template &lt;class MUTEX>
-Test_T&lt;MUTEX>::Test_T( const char * _name )
- : ACE_Task&lt;ACE_MT_SYNCH>()
- ,name_(_name)
- ,barrier_(TEST_THREAD_COUNT)
+Test_T&lt;MUTEX>::Test_T (const char *name)
+ : ACE_Task&lt;ACE_MT_SYNCH>(),
+ name_ (name),
+ barrier_ (TEST_THREAD_COUNT)
{
- ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\tTest_T (%s) created\n</font>", _name ));
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t|%T)\tTest_T (%s) created\n</font>",
+ name));
}
<font color=red>/* Activate the threads and create some test data...
*/</font>
-template &lt;class MUTEX>
-int Test_T&lt;MUTEX>::run(void)
+template &lt;class MUTEX> int
+Test_T&lt;MUTEX>::run (void)
{
- <font color=red>// Try to activate the set of threads that will test the mutex</font>
- if( this->open() == -1 )
- {
- return -1;
- }
+ <font color=red>// Try to activate the set of threads that will test the mutex</font>
+ if (this->open () == -1)
+ return -1;
- <font color=red>// Create a set of messages. I chose twice the thread count</font>
- <font color=red>// so that we can see how they get distributed.</font>
- for( int i = 0 ; i &lt; TEST_THREAD_COUNT*2 ; ++i )
+ <font color=red>// Create a set of messages. I chose twice the thread count so that</font>
+ <font color=red>// we can see how they get distributed.</font>
+ for (int i = 0; i &lt; TEST_THREAD_COUNT*2; ++i)
{
- <font color=red>// A message block big enough for a simple message.</font>
- ACE_Message_Block * message = new ACE_Message_Block(64);
-
- <font color=red>// Put some text into the message block so that we can</font>
- <font color=red>// know what's going on when we get to svc()</font>
- sprintf(message->wr_ptr(),"<font color=green>Message Number %d</font>",i);
- message->wr_ptr( strlen(message->rd_ptr())+1 );
-
- <font color=red>// Send the message to the thread pool</font>
- if( this->send(message) == -1 )
- {
- break;
- }
+ <font color=red>// A message block big enough for a simple message.</font>
+ ACE_Message_Block *message;
+
+ ACE_NEW_RETURN (message,
+ ACE_Message_Block (64),
+ -1);
+
+ <font color=red>// Put some text into the message block so that we can know</font>
+ <font color=red>// what's going on when we get to svc()</font>
+ sprintf (message->wr_ptr (),
+ "<font color=green>Message Number %d</font>",
+ i);
+ message->wr_ptr (<font color=#008888>ACE_OS::strlen</font> (message->rd_ptr ()) + 1);
+
+ <font color=red>// Send the message to the thread pool</font>
+ if (this->send (message) == -1)
+ break;
}
- <font color=red>// Send a hangup to the thread pool so that we can exit.</font>
- if( this->send() == -1 )
- {
- return -1;
- }
+ <font color=red>// Send a hangup to the thread pool so that we can exit.</font>
+ if (this->send () == -1)
+ return -1;
- <font color=red>// Wait for all of the threads to exit and then return to the client.</font>
- return this->wait();
+ <font color=red>// Wait for all of the threads to exit and then return to the client.</font>
+ return this->wait ();
}
<font color=red>/* Send a message to the thread pool
*/</font>
-template &lt;class MUTEX>
-int Test_T&lt;MUTEX>::send( ACE_Message_Block * _message )
+template &lt;class MUTEX> int
+Test_T&lt;MUTEX>::send (ACE_Message_Block *message)
{
- <font color=red>// If no message was provided, create a hangup message.</font>
- if( ! _message )
+ <font color=red>// If no message was provided, create a hangup message.</font>
+ if (message == 0)
+ ACE_NEW_RETURN (message,
+ ACE_Message_Block (0,
+ <font color=#008888>ACE_Message_Block::MB_HANGUP</font>),
+ -1);
+
+ <font color=red>// Use the duplicate() method when sending the message. For this</font>
+ <font color=red>// simple application, that may be overkill but it's a good habit.</font>
+ <font color=red>// duplicate() will increment the reference count so that each user</font>
+ <font color=red>// of the message can release() it when done. The last user to call</font>
+ <font color=red>// release() will cause the data to be deleted.</font>
+ if (this->putq (message->duplicate ()) == -1)
{
- _message = new
- ACE_Message_Block(0,<font color=#008888>ACE_Message_Block::MB_HANGUP</font>);
+ <font color=red>// Error? release() the message block and return failure.</font>
+ message->release ();
+ return -1;
}
- <font color=red>// Use the duplicate() method when sending the message. For</font>
- <font color=red>// this simple application, that may be overkill but it's a</font>
- <font color=red>// good habit. duplicate() will increment the reference count </font>
- <font color=red>// so that each user of the message can release() it when</font>
- <font color=red>// done. The last user to call release() will cause the data</font>
- <font color=red>// to be deleted.</font>
- if( this->putq(_message->duplicate()) == -1 )
- {
- <font color=red>// Error? release() the message block and return failure.</font>
- _message->release();
- return -1;
- }
+ <font color=red>// release() the data to prevent memory leaks.</font>
+ message->release();
- <font color=red>// release() the data to prevent memory leaks.</font>
- _message->release();
-
- return 0;
+ return 0;
}
<font color=red>/* A farily typical open(). Just activate the set of threads and return.
*/</font>
-template &lt;class MUTEX>
-int Test_T&lt;MUTEX>::open( void * _arg )
+template &lt;class MUTEX> int
+Test_T&lt;MUTEX>::open (void *arg)
{
- ACE_UNUSED_ARG(_arg);
- return this->activate(THR_NEW_LWP, TEST_THREAD_COUNT);
+ ACE_UNUSED_ARG(_arg);
+ return this->activate (THR_NEW_LWP,
+ TEST_THREAD_COUNT);
}
<font color=red>/* svc() is also fairly typical. The new part is the use of the guard
to simulate protection of shared resources.
*/</font>
-template &lt;class MUTEX>
-int Test_T&lt;MUTEX>::svc(void)
+template &lt;class MUTEX> int
+Test_T&lt;MUTEX>::svc (void)
{
- <font color=red>// Keep a simple thread identifier. We could always use the</font>
- <font color=red>// thread id but this is a nice, simple number.</font>
- int my_number = ++thread_num_;
-
- ACE_DEBUG ((LM_INFO, "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() Entry\n</font>",
- my_number));
-
- <font color=red>// Wait for all of threads to get started so that they all</font>
- <font color=red>// have a fair shot at the message queue. Comment this out</font>
- <font color=red>// and see how the behaviour changes. Does it surprise you?</font>
- barrier_.wait();
-
- ACE_Message_Block * message;
- int mcount = 0;
-
- <font color=red>// This would usually be an almost-infinite loop. Instead,</font>
- <font color=red>// I've governed it so that no single thread can get more than </font>
- <font color=red>// "<font color=green>thread count</font>" number of messages. You'll see that with</font>
- <font color=red>// ACE_Mutex, this is just about the only way to keep the</font>
- <font color=red>// first thread from getting all the action. Ths is obviously </font>
- <font color=red>// just for sake of the test since you don't want your</font>
- <font color=red>// real-world app to exit after a fixed number of messages!</font>
- while( mcount &lt; TEST_THREAD_COUNT )
+ <font color=red>// Keep a simple thread identifier. We could always use the</font>
+ <font color=red>// thread id but this is a nice, simple number.</font>
+ int my_number = ++thread_num_;
+
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() Entry\n</font>",
+ my_number));
+
+ <font color=red>// Wait for all of threads to get started so that they all have a</font>
+ <font color=red>// fair shot at the message queue. Comment this out and see how the</font>
+ <font color=red>// behaviour changes. Does it surprise you?</font>
+ barrier_.wait ();
+
+ ACE_Message_Block *message;
+ int mcount = 0;
+
+ <font color=red>// This would usually be an almost-infinite loop. Instead, I've</font>
+ <font color=red>// governed it so that no single thread can get more than "thread</font>
+ <font color=red>// count" number of messages. You'll see that with ACE_Mutex, this</font>
+ <font color=red>// is just about the only way to keep the first thread from getting</font>
+ <font color=red>// all the action. Ths is obviously just for sake of the test since</font>
+ <font color=red>// you don't want your real-world app to exit after a fixed number</font>
+ <font color=red>// of messages!</font>
+ while (mcount &lt; TEST_THREAD_COUNT)
{
- <font color=red>// Get a message. Since the message queue is already</font>
- <font color=red>// thread-safe we don't have to guard it. In fact, moving </font>
- <font color=red>// the guard up above getq() will decrease your</font>
- <font color=red>// parallelization.</font>
- if( getq(message) == -1 )
- {
- break;
- }
-
- <font color=red>// Now we pretend that there are shared resources required </font>
- <font color=red>// to process the data. We grab the mutex through the</font>
- <font color=red>// guard and "<font color=green>do work</font>". In a real application, you'll</font>
- <font color=red>// want to keep these critical sections as small as</font>
- <font color=red>// possible since they will reduce the usefulness of</font>
- <font color=red>// multi-threading.</font>
- guard_t guard(mutex_);
-
- <font color=red>// Increase our message count for the debug output and the</font>
- <font color=red>// governor.</font>
- ++mcount;
-
- <font color=red>// Check for a hangup request...</font>
- <font color=red>// Notice the use of release() again to prevent leaks</font>
- if( message->msg_type() == <font color=#008888>ACE_Message_Block::MB_HANGUP</font> )
+ <font color=red>// Get a message. Since the message queue is already</font>
+ <font color=red>// thread-safe we don't have to guard it. In fact, moving the</font>
+ <font color=red>// guard up above getq() will decrease your parallelization.</font>
+ if (getq (message) == -1)
+ break;
+
+ <font color=red>// Now we pretend that there are shared resources required to</font>
+ <font color=red>// process the data. We grab the mutex through the guard and</font>
+ <font color=red>// "<font color=green>do work</font>". In a real application, you'll want to keep these</font>
+ <font color=red>// critical sections as small as possible since they will reduce</font>
+ <font color=red>// the usefulness of multi-threading.</font>
+ guard_t guard (mutex_);
+
+ <font color=red>// Increase our message count for the debug output and the</font>
+ <font color=red>// governor.</font>
+ ++mcount;
+
+ <font color=red>// Check for a hangup request... Notice the use of release()</font>
+ <font color=red>// again to prevent leaks</font>
+ if (message->msg_type () == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>)
{
- message->release();
- break;
+ message->release ();
+ break;
}
- <font color=red>// Display the message so that we can see if things are</font>
- <font color=red>// working the way we want.</font>
- ACE_DEBUG ((LM_INFO, "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() received message #%d (%s)\n</font>",
- my_number,mcount,message->rd_ptr()));
+ <font color=red>// Display the message so that we can see if things are working</font>
+ <font color=red>// the way we want.</font>
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() received message #%d (%s)\n</font>",
+ my_number,
+ mcount,
+ message->rd_ptr ()));
- <font color=red>// Pretend that the work takes some time to complete.</font>
- <font color=red>// Remember, we're holding that lock during this time!</font>
- <font color=#008888>ACE_OS::sleep</font>(1);
+ <font color=red>// Pretend that the work takes some time to complete. Remember,</font>
+ <font color=red>// we're holding that lock during this time!</font>
+ <font color=#008888>ACE_OS::sleep</font> (1);
- <font color=red>// No leaks...</font>
- message->release();
+ <font color=red>// No leaks...</font>
+ message->release ();
}
- <font color=red>// Send a hangup to the other threads in the pool. If we don't</font>
- <font color=red>// do this then wait() will never exit since all of the other</font>
- <font color=red>// threads are still blocked on getq().</font>
- this->send();
+ <font color=red>// Send a hangup to the other threads in the pool. If we don't do</font>
+ <font color=red>// this then wait() will never exit since all of the other threads</font>
+ <font color=red>// are still blocked on getq().</font>
+ this->send ();
- return(0);
+ return 0;
};
-<font color=blue>#endif</font> <font color=red>// TEST_T_C</font>
+<font color=blue>#endif</font> <font color=red>/* TEST_T_C */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/018/page05.html b/docs/tutorials/018/page05.html
index 7d78a18cae0..8304aa67104 100644
--- a/docs/tutorials/018/page05.html
+++ b/docs/tutorials/018/page05.html
@@ -17,9 +17,8 @@ is parameterized with our mutex of choice and "named". Using the Test
template we're able to reuse all of the code with practially no
retyping and certainly much less chance of error!
<HR>
-<PRE>
<HR width=50%><P><center>Token_i.h</center><HR width=50%>
-
+<PRE>
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>TOKEN_I_H</font>
@@ -36,16 +35,13 @@ retyping and certainly much less chance of error!
class Token : public Test_T&lt;ACE_Token>
{
public:
- Token(void)
- : Test_T&lt;ACE_Token>("<font color=green>Token</font>")
- {}
+ Token (void): Test_T&lt;ACE_Token> ("<font color=green>Token</font>") {}
};
-<font color=blue>#endif</font> <font color=red>// TOKEN_I_H</font>
+<font color=blue>#endif</font> <font color=red>/* TOKEN_I_H */</font>
</PRE>
-<PRE>
<HR width=50%><P><center>Mutex_i.h</center><HR width=50%>
-
+<PRE>
<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>MUTEX_I_H</font>
@@ -59,12 +55,10 @@ public:
class Mutex : public Test_T&lt;ACE_Mutex>
{
public:
- Mutex(void)
- : Test_T&lt;ACE_Mutex>("<font color=green>Mutex</font>")
- {}
+ Mutex (void) : Test_T&lt;ACE_Mutex> ("<font color=green>Mutex</font>") {}
};
-<font color=blue>#endif</font> <font color=red>// MUTEX_I_H</font>
+<font color=blue>#endif</font> <font color=red>/* MUTEX_I_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/019/page01.html b/docs/tutorials/019/page01.html
index c4ab2a7d300..2d74f78c874 100644
--- a/docs/tutorials/019/page01.html
+++ b/docs/tutorials/019/page01.html
@@ -34,5 +34,6 @@
myself. This tutorial and the next are very simple-minded and
primitive. Anyone who wants to provide more realistic
replacements is encouraged to drop me a note
- (<A HREF="mailto:jcej@lads.com">jcej@lads.com</A>).<P><HR WIDTH="100%">
+ (<A HREF="mailto:jcej@lads.com">jcej@lads.com</A>).
+<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/019/page02.html b/docs/tutorials/019/page02.html
index d6a42dc8aef..722797e6ba4 100644
--- a/docs/tutorials/019/page02.html
+++ b/docs/tutorials/019/page02.html
@@ -21,7 +21,9 @@ can be created external to your application and can persist beyond
it's lifetime. In fact, you can use shared memory to create a layer
of persistence between application instances (at least, until the
machine comes down.)
-<HR><PRE>
+<HR>
+<PRE>
+<font color=red>// $Id$</font>
<font color=red>/*
The client and server both need to know the shared memory key and
@@ -30,98 +32,123 @@ machine comes down.)
*/</font>
<font color=blue>#include</font> "<font color=green>shmem.h</font>"
-int main (int, char *[])
+<font color=blue>#if defined</font> (<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+int
+main (int, char *[])
{
- <font color=red>/*
- You can use the ACE_Malloc template to create memory pools
- from various shared memory strategies. It's really cool.
- We're not going to use it.
-
- Instead, I want to get to the roots of it all and directly
- use ACE_Shared_Memory_SV. Like many ACE objects, this is a
- wrapper around OS services.
-
- With this constructor we create a shared memory area to
- use. The ACE_CREATE flag will cause it to be created if it
- doesn't already exist. The SHM_KEY value (from shmem.h)
- uniquely identifies the segment and allows other apps to
- attach to the same segment. Execute 'ipcs -m' before and
- after starting this app to see that the segment is created.
- (I can't for the life of me correlate the SHM_KEY value back
- to the key/id reported by ipcs though.)
- */</font>
- ACE_Shared_Memory_SV shm_server (SHM_KEY, SHMSZ,
- <font color=#008888>ACE_Shared_Memory_SV::ACE_CREATE</font>);
-
- <font color=red>/*
- The constructor created the segment for us but we still need
- to map the segment into our address space. (Note that you
- can pass a value to malloc() but it will be silently
- igored.) The void* (cast to char*) that is returned will
- point to the beginning of the shared segment.
- */</font>
- char *shm = (char *) shm_server.malloc ();
-
- <font color=red>/*
- This second pointer will be used to walk through the block
- of memory...
- */</font>
- char *s = shm;
-
- <font color=red>/*
- Out of curiosity, I added this output message. The tests
- I've done so far show me the same address for client and
- server. What does your OS tell you?
- */</font>
- ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
- shm ));
-
- <font color=red>/*
- At this point, our application can use the pointer just like
- any other given to us by new or malloc. For our purposes,
- we'll copy in the alpabet as a null-terminated string.
- */</font>
- for (char c = 'a'; c &lt;= 'z'; c++)
- *s++ = c;
-
- *s = '\0';
-
- <font color=red>/*
- Using a simple not-too-busy loop, we'll wait for the client
- (or anyone else) to change the first byte in the shared area
- to a '*' character. This is where you would rather use
- semaphores or some similar "<font color=green>resource light</font>" approach.
- */</font>
- while (*shm != '*')
- <font color=#008888>ACE_OS::sleep</font> (1);
-
- <font color=red>/*
- Let's see what the client did to the segment...
- */</font>
- for (char *s = shm; *s != '\0'; s++)
- {
- putchar (*s);
- }
- putchar ('\n');
-
- <font color=red>/*
- If you're done with the segment and ready for it to be
- removed from the system, use the remove() method. Once the
- program exits, do 'ipcs -m' again and you'll see that the
- segment is gone. If you just want to terminate your use of
- the segment but leave it around for other apps, use the
- close() method instead.
-
- The free() method may be tempting but it doesn't actually do
- anything. If your app is *really* done with the shared
- memory then use either close() or remove().
- */</font>
- if (shm_server.remove () &lt; 0)
- ACE_ERROR ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>remove</font>"));
-
- return 0;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>System V Shared Memory not available on this platform\n</font>"),
+ 100);
+}
+#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
+int
+main (int, char *argv[])
+{
+ <font color=red>/*
+ You can use the ACE_Malloc template to create memory pools
+ from various shared memory strategies. It's really cool.
+ We're not going to use it.
+
+ Instead, I want to get to the roots of it all and directly
+ use ACE_Shared_Memory_SV. Like many ACE objects, this is a
+ wrapper around OS services.
+
+ With this constructor we create a shared memory area to
+ use. The ACE_CREATE flag will cause it to be created if it
+ doesn't already exist. The SHM_KEY value (from shmem.h)
+ uniquely identifies the segment and allows other apps to
+ attach to the same segment. Execute 'ipcs -m' before and
+ after starting this app to see that the segment is created.
+ (I can't for the life of me correlate the SHM_KEY value back
+ to the key/id reported by ipcs though.)
+ */</font>
+ ACE_Shared_Memory_SV shm_server (SHM_KEY, SHMSZ,
+ <font color=#008888>ACE_Shared_Memory_SV::ACE_CREATE</font>);
+
+ <font color=red>/*
+ The constructor created the segment for us but we still need
+ to map the segment into our address space. (Note that you
+ can pass a value to malloc() but it will be silently
+ igored.) The void* (cast to char*) that is returned will
+ point to the beginning of the shared segment.
+ */</font>
+ char *shm = (char *) shm_server.malloc ();
+
+ <font color=red>/*
+ Since we're asking to create the segment, we will fail if it
+ already exists. We could fall back and simply attach to it
+ like the client but I'd rather not assume it was a previous
+ instance of this app that left the segment around.
+ */</font>
+ if (shm == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>%p\n\t(%P|%t) Cannot create shared memory segment.\n</font>"
+ "<font color=green>\tUse 'ipcs' to see if it already exists\n</font>",
+ argv[0]),
+ 100);
+
+ <font color=red>/*
+ This second pointer will be used to walk through the block
+ of memory...
+ */</font>
+ char *s = shm;
+
+ <font color=red>/*
+ Out of curiosity, I added this output message. The tests
+ I've done so far show me the same address for client and
+ server. What does your OS tell you?
+ */</font>
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
+ shm ));
+
+ <font color=red>/*
+ At this point, our application can use the pointer just like
+ any other given to us by new or malloc. For our purposes,
+ we'll copy in the alpabet as a null-terminated string.
+ */</font>
+ for (char c = 'a'; c &lt;= 'z'; c++)
+ *s++ = c;
+
+ *s = '\0';
+
+ <font color=red>/*
+ Using a simple not-too-busy loop, we'll wait for the client
+ (or anyone else) to change the first byte in the shared area
+ to a '*' character. This is where you would rather use
+ semaphores or some similar "<font color=green>resource light</font>" approach.
+ */</font>
+ while (*shm != '*')
+ <font color=#008888>ACE_OS::sleep</font> (1);
+
+ <font color=red>/*
+ Let's see what the client did to the segment...
+ */</font>
+ for (s = shm; *s != '\0'; s++)
+ putchar (*s);
+
+ putchar ('\n');
+
+ <font color=red>/*
+ If you're done with the segment and ready for it to be
+ removed from the system, use the remove() method. Once the
+ program exits, do 'ipcs -m' again and you'll see that the
+ segment is gone. If you just want to terminate your use of
+ the segment but leave it around for other apps, use the
+ close() method instead.
+
+ The free() method may be tempting but it doesn't actually do
+ anything. If your app is *really* done with the shared
+ memory then use either close() or remove().
+ */</font>
+ if (shm_server.remove () &lt; 0)
+ ACE_ERROR ((LM_ERROR,
+ "<font color=green>%p\n</font>",
+ "<font color=green>remove</font>"));
+ return 0;
}
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/019/page03.html b/docs/tutorials/019/page03.html
index 76a9c48229e..e5202514c21 100644
--- a/docs/tutorials/019/page03.html
+++ b/docs/tutorials/019/page03.html
@@ -17,67 +17,80 @@ CREATE flag with no ill effects but note the use of close() instead of
remove(). Picking the correct detachment method is rather important!
<HR>
<PRE>
+<font color=red>// $Id$</font>
<font color=red>// Again, the common stuff</font>
<font color=blue>#include</font> "<font color=green>shmem.h</font>"
-int main (int, char *[])
+<font color=blue>#if defined</font>(<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+int
+main (int, char *[])
{
- <font color=red>/*
- Attach ourselves to the shared memory segment.
- */</font>
- ACE_Shared_Memory_SV shm_client (SHM_KEY, SHMSZ);
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>System V Shared Memory not available on this platform\n</font>"),
+ 100);
+}
+#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
+int
+main (int, char *[])
+{
+ <font color=red>/*
+ Attach ourselves to the shared memory segment.
+ */</font>
+ ACE_Shared_Memory_SV shm_client (SHM_KEY, SHMSZ);
- <font color=red>/*
- Get our reference to the segment...
- */</font>
- char *shm = (char *) shm_client.malloc ();
+ <font color=red>/*
+ Get our reference to the segment...
+ */</font>
+ char *shm = (char *) shm_client.malloc ();
- <font color=red>/*
- If the segment identified by SHM_KEY didn't exist then we'll
- get back a 0 from malloc(). You should do this check even
- if you include the CREATE flag 'cause you never know when it
- might fail.
- */</font>
- if( ! shm )
- {
- ACE_ERROR_RETURN ((LM_ERROR,"<font color=green>(%P|%t) Could not get the segment!\n</font>"),100);
- }
+ <font color=red>/*
+ If the segment identified by SHM_KEY didn't exist then we'll
+ get back a 0 from malloc(). You should do this check even
+ if you include the CREATE flag 'cause you never know when it
+ might fail.
+ */</font>
+ if (shm == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P|%t) Could not get the segment!\n</font>"),
+ 100);
- <font color=red>/*
- Does this match what your server said?
- */</font>
- ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
- shm ));
+ <font color=red>/*
+ Does this match what your server said?
+ */</font>
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
+ shm ));
- <font color=red>/*
- Show the shared data to the user and convert it all to
- uppper-case along the way.
- */</font>
- for (char *s = shm; *s != '\0'; s++)
+ <font color=red>/*
+ Show the shared data to the user and convert it all to
+ uppper-case along the way.
+ */</font>
+ for (char *s = shm; *s != '\0'; s++)
{
- putchar (*s);
- *s = toupper(*s);
+ putchar (*s);
+ *s = toupper(*s);
}
- putchar ('\n');
+ putchar ('\n');
- <font color=red>/*
- Flag the server that we're done.
- */</font>
- *shm = '*';
+ <font color=red>/*
+ Flag the server that we're done.
+ */</font>
+ *shm = '*';
- <font color=red>/*
- Here, we use close() instead of remove(). Remember, that
- will just remove our attachment to the segment. Look
- closely at the 'nattch' column of the ipcs output & you'll
- see that this decrements it by one.
- */</font>
- shm_client.close();
+ <font color=red>/*
+ Here, we use close() instead of remove(). Remember, that
+ will just remove our attachment to the segment. Look
+ closely at the 'nattch' column of the ipcs output & you'll
+ see that this decrements it by one.
+ */</font>
+ shm_client.close();
- return 0;
+ return 0;
}
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/019/page04.html b/docs/tutorials/019/page04.html
index 635659e6204..79f00aefbb7 100644
--- a/docs/tutorials/019/page04.html
+++ b/docs/tutorials/019/page04.html
@@ -29,86 +29,122 @@ That's not to say you shouldn't try... Just try carefully and test a lot!
<HR>
<HR width=50%><P><center>server2.cpp</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
<font color=blue>#include</font> "<font color=green>shmem.h</font>"
-int
+<font color=blue>#if defined</font> (<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+int
main (int, char *[])
{
- <font color=red>// Be sure the segment is sized to hold our object.</font>
- ACE_Shared_Memory_SV shm_server (SHM_KEY, sizeof(SharedData),
- <font color=#008888>ACE_Shared_Memory_SV::ACE_CREATE</font>);
-
- char *shm = (char *) shm_server.malloc ();
-
- ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
- shm ));
-
- <font color=red>/*
- Use the placement new syntax to stuff the object into the
- correct location. I think they generally reserve this for
- the advanced class...
- */</font>
- SharedData * sd = new(shm) SharedData;
-
- <font color=red>// Use the set() method to put some data into the object</font>
- sd->set();
-
- <font color=red>// Set the 'available' flag to zero so that we can wait on it</font>
- sd->available(0);
-
- <font color=red>/*
- Another cheesy busy loop while we wait for the object to
- become available. The cool way would be to hide a semaphore
- or two behind this method call & eliminate the sleep.
- */</font>
- while ( ! sd->available() )
- <font color=#008888>ACE_OS::sleep</font> (1);
-
- <font color=red>// Show the user what's in the segment</font>
- sd->show();
-
- <font color=red>// All done.</font>
- if (shm_server.remove () &lt; 0)
- ACE_ERROR ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>remove</font>"));
-
- return 0;
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>System V Shared Memory not available on this platform\n</font>"),
+ 100);
+}
+#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
+int
+main (int, char *argv[])
+{
+ <font color=red>// Be sure the segment is sized to hold our object.</font>
+ ACE_Shared_Memory_SV shm_server (SHM_KEY,
+ sizeof (SharedData),
+ <font color=#008888>ACE_Shared_Memory_SV::ACE_CREATE</font>);
+ char *shm = (char *) shm_server.malloc ();
+
+ if (shm == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>%p\n\t(%P|%t) Cannot create shared memory segment.\n</font>"
+ "<font color=green>\tUse 'ipcs' to see if it already exists\n</font>",
+ argv[0]),
+ 100);
+
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
+ shm ));
+
+ <font color=red>/*
+ Use the placement new syntax to stuff the object into the
+ correct location. I think they generally reserve this for
+ the advanced class...
+ */</font>
+ SharedData *sd = new (shm) SharedData;
+
+ <font color=red>// Use the set() method to put some data into the object</font>
+ sd->set ();
+
+ <font color=red>// Set the 'available' flag to zero so that we can wait on it</font>
+ sd->available (0);
+
+ <font color=red>/*
+ Another cheesy busy loop while we wait for the object to
+ become available. The cool way would be to hide a semaphore
+ or two behind this method call & eliminate the sleep.
+ */</font>
+ while (sd->available () == 0)
+ <font color=#008888>ACE_OS::sleep</font> (1);
+
+ <font color=red>// Show the user what's in the segment</font>
+ sd->show ();
+
+ <font color=red>// All done.</font>
+ if (shm_server.remove () &lt; 0)
+ ACE_ERROR ((LM_ERROR,
+ "<font color=green>%p\n</font>",
+ "<font color=green>remove</font>"));
+ return 0;
}
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<HR width=50%><P><center>client2.cpp</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
<font color=blue>#include</font> "<font color=green>shmem.h</font>"
-int main (int, char *[])
+<font color=blue>#if defined</font>(<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+int
+main (int, char *[])
{
- ACE_Shared_Memory_SV shm_client (SHM_KEY, sizeof(SharedData));
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>System V Shared Memory not available on this platform\n</font>"),
+ 100);
+}
+#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
+int
+main (int, char *[])
+{
+ ACE_Shared_Memory_SV shm_client (SHM_KEY,
+ sizeof (SharedData));
- char *shm = (char *) shm_client.malloc ();
-
- ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
- shm ));
-
- <font color=red>/*
- More placement new. The constructor parameter prevents
- clobbering what the server may have written with it's show()
- method.
- */</font>
- SharedData * sd = new(shm) SharedData(0);
-
- <font color=red>// Show it</font>
- sd->show();
- <font color=red>// Change it</font>
- sd->set();
- <font color=red>// Advertise it</font>
- sd->available(1);
-
- shm_client.close();
+ char *shm = (char *) shm_client.malloc ();
+
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Shared Memory is at 0x%x\n</font>",
+ shm));
+
+ <font color=red>/*
+ More placement new. The constructor parameter prevents
+ clobbering what the server may have written with it's show()
+ method.
+ */</font>
+ SharedData *sd = new (shm) SharedData (0);
+
+ <font color=red>// Show it</font>
+ sd->show ();
+
+ <font color=red>// Change it</font>
+ sd->set ();
+
+ <font color=red>// Advertise it</font>
+ sd->available (1);
+
+ shm_client.close ();
- return 0;
+ return 0;
}
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/019/page05.html b/docs/tutorials/019/page05.html
index b04217a9551..7611341ac98 100644
--- a/docs/tutorials/019/page05.html
+++ b/docs/tutorials/019/page05.html
@@ -18,6 +18,7 @@
<HR>
<HR width=50%><P><center>shmem.h</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>SHMEM_H</font>
<font color=blue>#define</font> <font color=purple>SHMEM_H</font>
@@ -39,52 +40,59 @@
class SharedData
{
public:
- <font color=red>// Construct the object and optionally initialize buf_.</font>
- SharedData(int _initialize = 1);
-
- <font color=red>// Put some data into buf_</font>
- void set(void);
- <font color=red>// Show the data in buf_</font>
- void show(void);
- <font color=red>// What is the value of available_</font>
- int available(void);
- <font color=red>// Set the value of available_</font>
- void available(int _available);
+ <font color=red>// Construct the object and optionally initialize buf_.</font>
+ SharedData (int initialized = 1);
+
+ <font color=red>// Put some data into buf_</font>
+ void set (void);
+
+ <font color=red>// Show the data in buf_</font>
+ void show (void);
+
+ <font color=red>// What is the value of available_</font>
+ int available (void);
+
+ <font color=red>// Set the value of available_</font>
+ void available (int not_in_use);
protected:
- <font color=red>// Big enough for a simple message</font>
- char buf_[128];
- <font color=red>// A cheap mutex</font>
- int available_;
+ <font color=red>// Big enough for a simple message</font>
+ char buf_[128];
+ <font color=red>// A cheap mutex</font>
+ int available_;
};
-<font color=blue>#endif</font> <font color=red>// SHMEM_H</font>
+<font color=blue>#endif</font> <font color=red>/* SHMEM_H */</font>
</PRE>
<HR width=50%><P><center>shmem.cpp</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
<font color=blue>#include</font> "<font color=green>shmem.h</font>"
+#if ! defined (ACE_LACKS_SYSV_SHMEM)
+
<font color=red>/*
Set the available_ flag to zero & optionally initialize the buf_
area.
*/</font>
-<font color=#008888>SharedData::SharedData</font>(int _initialize)
- : available_(0)
+
+<font color=#008888>SharedData::SharedData</font> (int initialize)
+ : available_ (0)
{
- if( _initialize )
- {
- <font color=#008888>ACE_OS::sprintf</font>(buf_,"<font color=green>UNSET\n</font>");
- }
+ if (initialize)
+ <font color=#008888>ACE_OS::sprintf</font> (buf_, "<font color=green>UNSET\n</font>");
}
<font color=red>/*
Write the process ID into the buffer. This will prove to us that
the data really is shared between the client and server.
*/</font>
-void <font color=#008888>SharedData::set</font>(void)
+void <font color=#008888>SharedData::set</font> (void)
{
- <font color=#008888>ACE_OS::sprintf</font>(buf_,"<font color=green>My PID is (%d)\n</font>",ACE_OS::getpid());
+ <font color=#008888>ACE_OS::sprintf</font> (buf_,
+ "<font color=green>My PID is (%d)\n</font>",
+ <font color=#008888>ACE_OS::getpid</font> ());
}
<font color=red>/*
@@ -92,21 +100,24 @@ void <font color=#008888>SharedData::set</font>(void)
*/</font>
void <font color=#008888>SharedData::show</font>(void)
{
- ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t) Shared Data text is (%s)\n</font>",
- buf_ ));
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>(%P|%t) Shared Data text is (%s)\n</font>",
+ buf_));
}
<font color=red>// Show flag</font>
int <font color=#008888>SharedData::available</font>(void)
{
- return available_;
+ return available_;
}
<font color=red>// Set flag</font>
-void <font color=#008888>SharedData::available</font>(int _available)
+void <font color=#008888>SharedData::available</font>(int a)
{
- available_ = _available;
+ available_ = a;
}
+
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/019/page06.html b/docs/tutorials/019/page06.html
index 65b8c7ac7ca..3951e6cfd14 100644
--- a/docs/tutorials/019/page06.html
+++ b/docs/tutorials/019/page06.html
@@ -23,6 +23,5 @@
<li><A HREF="shmem.cpp">shmem.cpp</A>
<li><A HREF="Makefile">Makefile</A>
</ul>
- <HR>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER>
diff --git a/docs/tutorials/020/page02.html b/docs/tutorials/020/page02.html
index dc5f293b16a..bb21f07d60f 100644
--- a/docs/tutorials/020/page02.html
+++ b/docs/tutorials/020/page02.html
@@ -25,6 +25,8 @@
<hr>
<PRE>
+<font color=red>// $Id$</font>
+
<font color=blue>#include</font> "<font color=green>mmap.h</font>"
int
@@ -50,7 +52,7 @@ main (int, char *[])
while (*shm != '*')
<font color=#008888>ACE_OS::sleep</font> (1);
- for (char *s = shm; *s != '\0'; s++)
+ for (s = shm; *s != '\0'; s++)
{
putchar (*s);
}
diff --git a/docs/tutorials/020/page03.html b/docs/tutorials/020/page03.html
index d7b41c8e51e..9ff47b04670 100644
--- a/docs/tutorials/020/page03.html
+++ b/docs/tutorials/020/page03.html
@@ -17,6 +17,8 @@ There's no important difference between this and the SV client. Is
<hr>
<PRE>
+<font color=red>// $Id$</font>
+
<font color=blue>#include</font> "<font color=green>mmap.h</font>"
int main (int, char *[])
@@ -45,7 +47,6 @@ int main (int, char *[])
return 0;
}
-
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/020/page04.html b/docs/tutorials/020/page04.html
index 037b820b63e..93155c27c49 100644
--- a/docs/tutorials/020/page04.html
+++ b/docs/tutorials/020/page04.html
@@ -24,6 +24,8 @@ Imagine if you had an object that contained an image & then you mapped
<HR width=50%><P><center>server2.cpp</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
+
<font color=blue>#include</font> "<font color=green>mmap.h</font>"
int
@@ -56,6 +58,8 @@ main (int, char *[])
<HR width=50%><P><center>client2.cpp</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
+
<font color=blue>#include</font> "<font color=green>mmap.h</font>"
int main (int, char *[])
diff --git a/docs/tutorials/020/page05.html b/docs/tutorials/020/page05.html
index 04016a34532..0d85cc09afa 100644
--- a/docs/tutorials/020/page05.html
+++ b/docs/tutorials/020/page05.html
@@ -17,6 +17,7 @@ The mmap.h where we define stuff that needs to be shared between the
<hr>
<HR width=50%><P><center>mmap.h</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
<font color=blue>#ifndef</font> <font color=purple>MMAP_H</font>
<font color=blue>#define</font> <font color=purple>MMAP_H</font>
@@ -41,23 +42,25 @@ The mmap.h where we define stuff that needs to be shared between the
class SharedData
{
public:
- SharedData(int _initialize = 1);
+ SharedData (int initialize = 1);
- void set(void);
- void show(void);
- int available(void);
- void available(int _available);
+ void set (void);
+ void show (void);
+ int available (void);
+ void available (int not_in_use);
protected:
- char buf_[128];
- int available_;
+ char buf_[128];
+ int available_;
};
-<font color=blue>#endif</font> <font color=red>// MMAP_H</font>
+<font color=blue>#endif</font> <font color=red>/* MMAP_H */</font>
</PRE>
<HR width=50%><P><center>mmap.cpp</center><HR width=50%>
<PRE>
+<font color=red>// $Id$</font>
+
<font color=blue>#include</font> "<font color=green>mmap.h</font>"
<font color=#008888>SharedData::SharedData</font>(int _initialize)
diff --git a/docs/tutorials/021/page02.html b/docs/tutorials/021/page02.html
index 0c1a4014b61..2aac4677274 100644
--- a/docs/tutorials/021/page02.html
+++ b/docs/tutorials/021/page02.html
@@ -19,7 +19,8 @@
<li>Name the allocated region
</ul>
The rest of it is just critical sections and data manipulation.
-<hr><PRE>
+<hr>
+<PRE>
<font color=red>// $Id$</font>
@@ -29,126 +30,133 @@
*/</font>
<font color=blue>#include</font> "<font color=green>mpool.h</font>"
-int main (int, char *[])
+<font color=blue>#if defined</font>(<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+int
+main (int, char *[])
{
- <font color=red>/*
- Construction of an Allocator will create the memory pool and
- provide it with a name. The Constants class is also
- declared in mpool.h to keep server and client on the same
- page. The name is used to generate a unique semaphore which
- prevents simultaneous access to the pools housekeeping
- information. (Note that you still have to provide your own
- synch mechanisms for the data *you* put in the pool.)
- */</font>
- Allocator allocator(<font color=#008888>Constants::PoolName</font>);
-
- <font color=red>/*
- The Allocator class provides the pool() member so that you
- have access to the actual memory pool. A more robust
- implementation would behave more as a bridge class but this
- is good enough for what we're doing here.
- Once you have a reference to the pool, the malloc() method
- can be used to get some bytes. If successful, shm will
- point to the data. Otherwise, it will be zero.
- */</font>
- char *shm = (char *) allocator.pool().malloc (27);
-
- ACE_ASSERT( shm != 0 );
-
- <font color=red>/// FYI</font>
- ACE_DEBUG ((LM_INFO, "<font color=green>Shared memory is at 0x%x\n</font>", shm ));
-
- <font color=red>/*
- Something that we can do with a memory pool is map a name to
- a region provided by malloc. By doing this, we can
- communicate that name to the client as a rendezvous
- location. Again, a member of Constants is used to keep the
- client and server coordinated.
- */</font>
- if( allocator.pool().bind(<font color=#008888>Constants::RegionName</font>,shm) == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>Cannot bind the name '%s' to the pointer 0x%x\n</font>",
- <font color=#008888>Constants::RegionName</font>,shm), 100 );
- }
-
- <font color=red>/*
- One of the best ways to synch between different processes is
- through the use of semaphores. ACE_SV_Semaphore_Complex
- hides the gory details and lets us use them rather easily.
-
- Here, we'll create two semaphores: mutex and synch. mutex
- will be used to provide mutually exclusive access to the
- shared region for writting/reading. synch will be used to
- prevent the server from removing the memory pool before the
- client is done with it.
-
- Both semaphores are created in an initially locked state.
- */</font>
-
- ACE_SV_Semaphore_Complex mutex;
- ACE_ASSERT (mutex.open (<font color=#008888>Constants::SEM_KEY_1</font>,
- <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1);
-
- ACE_SV_Semaphore_Complex synch;
- ACE_ASSERT (synch.open (<font color=#008888>Constants::SEM_KEY_2</font>,
- <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1);
-
- <font color=red>/*
- We know the mutex is locked because we created it that way.
- Take a moment to write some data into the shared region.
- */</font>
- for (int i = 0; i &lt; <font color=#008888>Constants::SHMSZ</font>; i++)
- {
- shm[i] = <font color=#008888>Constants::SHMDATA</font>[i];
- }
-
- <font color=red>/*
- The client will be blocking on an acquire() of mutex. By
- releasing it here, the client can go look at the shared data.
- */</font>
- if (mutex.release () == -1)
- {
- ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p</font>", "<font color=green>server mutex.release</font>"));
- }
- <font color=red>/*
- Even though we created the synch semaphore in a locked
- state, if we attempt to acquire() it, we will block. Our
- design requires that the client release() synch when it is
- OK for us to remove the shared memory.
- */</font>
- else if (synch.acquire () == -1)
- {
- ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p</font>", "<font color=green>server synch.acquire</font>"));
- }
-
- <font color=red>/*
- This will remove all of the memory pool's resources. In the
- case where a memory mapped file is used, the physical file
- will also be removed.
- */</font>
- if (allocator.pool ().remove () == -1)
- {
- ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p\n</font>", "<font color=green>server allocator.remove</font>"));
- }
-
- <font color=red>/*
- We now have to cleanup the semaphores we created. Use the
- ipcs command to see that they did, indeed, go away after the
- server exits.
- */</font>
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>System V Semaphores not available on this platform.\n</font>"),100);
+}
+#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
+int
+main (int, char *[])
+{
+ <font color=red>/*
+ Construction of an Allocator will create the memory pool and
+ provide it with a name. The Constants class is also
+ declared in mpool.h to keep server and client on the same
+ page. The name is used to generate a unique semaphore which
+ prevents simultaneous access to the pools housekeeping
+ information. (Note that you still have to provide your own
+ synch mechanisms for the data *you* put in the poo.)
+ */</font>
+ Allocator allocator (<font color=#008888>Constants::PoolName</font>);
+
+ <font color=red>/*
+ The Allocator class provides the pool() member so that you
+ have access to the actual memory pool. A more robust
+ implementation would behave more as a bridge class but this
+ is good enough for what we're doing here.
+ Once you have a reference to the pool, the malloc() method
+ can be used to get some bytes. If successful, shm will
+ point to the data. Otherwise, it will be zero.
+ */</font>
+ char *shm = (char *) allocator.pool ().malloc (27);
+
+ ACE_ASSERT (shm != 0);
+
+ <font color=red>/// FYI</font>
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>Shared memory is at 0x%x\n</font>",
+ shm));
+
+ <font color=red>/*
+ Something that we can do with a memory pool is map a name to
+ a region provided by malloc. By doing this, we can
+ communicate that name to the client as a rendezvous
+ location. Again, a member of Constants is used to keep the
+ client and server coordinated.
+ */</font>
+ if (allocator.pool ().bind(<font color=#008888>Constants::RegionName</font>,shm) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>Cannot bind the name '%s' to the pointer 0x%x\n</font>",
+ <font color=#008888>Constants::RegionName</font>,
+ shm),
+ 100);
+
+ <font color=red>/*
+ One of the best ways to synch between different processes is
+ through the use of semaphores. ACE_SV_Semaphore_Complex
+ hides the gory details and lets us use them rather easily.
+
+ Here, we'll create two semaphores: mutex and synch. mutex
+ will be used to provide mutually exclusive access to the
+ shared region for writting/reading. synch will be used to
+ prevent the server from removing the memory pool before the
+ client is done with it.
+
+ Both semaphores are created in an initially locked state.
+ */</font>
- if (mutex.remove () == -1)
- {
- ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p\n</font>", "<font color=green>server mutex.remove</font>"));
- }
-
- if (synch.remove () == -1)
- {
- ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p\n</font>", "<font color=green>server synch.remove</font>"));
- }
+ ACE_SV_Semaphore_Complex mutex;
+ ACE_ASSERT (mutex.open (<font color=#008888>Constants::SEM_KEY_1</font>,
+ <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>,
+ 0) != -1);
+
+ ACE_SV_Semaphore_Complex synch;
+ ACE_ASSERT (synch.open (<font color=#008888>Constants::SEM_KEY_2</font>,
+ <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>,
+ 0) != -1);
+
+ <font color=red>/*
+ We know the mutex is locked because we created it that way.
+ Take a moment to write some data into the shared region.
+ */</font>
+ for (int i = 0; i &lt; <font color=#008888>Constants::SHMSZ</font>; i++)
+ shm[i] = <font color=#008888>Constants::SHMDATA</font>[i];
+
+ <font color=red>/*
+ The client will be blocking on an acquire() of mutex. By
+ releasing it here, the client can go look at the shared data.
+ */</font>
+ if (mutex.release () == -1)
+ ACE_ERROR ((LM_ERROR,
+ "<font color=green>(%P) %p</font>",
+ "<font color=green>server mutex.release</font>"));
+ <font color=red>/*
+ Even though we created the synch semaphore in a locked
+ state, if we attempt to acquire() it, we will block. Our
+ design requires that the client release() synch when it is
+ OK for us to remove the shared memory.
+ */</font>
+ else if (synch.acquire () == -1)
+ ACE_ERROR ((LM_ERROR,
+ "<font color=green>(%P) %p</font>",
+ "<font color=green>server synch.acquire</font>"));
+ <font color=red>/*
+ This will remove all of the memory pool's resources. In the
+ case where a memory mapped file is used, the physical file
+ will also be removed.
+ */</font>
+ if (allocator.pool ().remove () == -1)
+ ACE_ERROR ((LM_ERROR,
+ "<font color=green>(%P) %p\n</font>",
+ "<font color=green>server allocator.remove</font>"));
+ <font color=red>/*
+ We now have to cleanup the semaphores we created. Use the
+ ipcs command to see that they did, indeed, go away after the
+ server exits.
+ */</font>
- return 0;
-
+ if (mutex.remove () == -1)
+ ACE_ERROR ((LM_ERROR,
+ "<font color=green>(%P) %p\n</font>",
+ "<font color=green>server mutex.remove</font>"));
+ else if (synch.remove () == -1)
+ ACE_ERROR ((LM_ERROR,
+ "<font color=green>(%P) %p\n</font>",
+ "<font color=green>server synch.remove</font>"));
+ return 0;
}
<font color=red>/*
@@ -167,6 +175,8 @@ template class ACE_Read_Guard&lt;ACE_SV_Semaphore_Simple>;
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Write_Guard&lt;ACE_SV_Semaphore_Simple>
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Read_Guard&lt;ACE_SV_Semaphore_Simple>
<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font>
+
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/021/page03.html b/docs/tutorials/021/page03.html
index 017134a55e5..e2d6e0bf117 100644
--- a/docs/tutorials/021/page03.html
+++ b/docs/tutorials/021/page03.html
@@ -18,98 +18,110 @@
<li>Create an Allocator to access the pool
<li>Find the named region
</ul>
-<hr><PRE>
+<hr>
+<PRE>
<font color=red>// $Id$</font>
<font color=blue>#include</font> "<font color=green>mpool.h</font>"
-int main (int, char *[])
+<font color=blue>#if defined</font>(<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+int
+main (int, char *[])
{
- <font color=red>/*
- Use the same pool name used by the server when we create our
- Allocator. This assures us that we don't create a whole new
- pool.
- */</font>
- Allocator allocator(<font color=#008888>Constants::PoolName</font>);
-
- <font color=red>/*
- You can put anything in the memory pool. Not just the
- character array we want. The find() method till, therefore,
- return a void* that we will have to cast.
- */</font>
- void * region;
-
- <font color=red>/*
- We use find() to locate a named region in the pool. This is
- the counterpart to bind() used in the server.
- Here, we go try to find the region that the server has created
- and filled with data. If there was a problem getting the pool
- or finding the region, we'll get back -1 from find().
- */</font>
- if( allocator.pool().find(<font color=#008888>Constants::RegionName</font>,region) == -1 )
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>Cannot find the name '%s'\n</font>",
- <font color=#008888>Constants::RegionName</font>), 100 );
- }
-
- <font color=red>/*
- Since find() returns us a void*, we cast it here to the char*
- that we want.
- */</font>
- char *shm = (char *)region;
-
- ACE_DEBUG ((LM_INFO, "<font color=green>Shared memory is at 0x%x\n</font>", shm ));
-
- <font color=red>/*
- The same pair of semaphores as used by the server are created
- here. We probably don't need the CREATE flag since the server
- should have already done that. There may be some very small
- windows, however, where the server would have created the
- memory pool but not yet gotten to the semaphores.
- */</font>
- ACE_SV_Semaphore_Complex mutex;
- ACE_ASSERT (mutex.open (<font color=#008888>Constants::SEM_KEY_1</font>,
- <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1);
-
- ACE_SV_Semaphore_Complex synch;
- ACE_ASSERT (synch.open (<font color=#008888>Constants::SEM_KEY_2</font>,
- <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>, 0) != -1);
-
- <font color=red>/*
- It doesn't matter if we created 'mutex' or if the server did.
- In either case, it was created in a locked state and we will
- block here until somebody unlocks it. In our scenario, that
- will have to be the server.
- */</font>
- if (mutex.acquire () == -1)
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P) client mutex.acquire</font>"), 1);
- }
-
- <font color=red>/*
- Now that we know it is safe to access the data, we'll run
- through and make sure that it contains what we think the server
- supplied.
- */</font>
- for (int i = 0; i &lt; <font color=#008888>Constants::SHMSZ</font>; i++)
- {
- ACE_ASSERT (<font color=#008888>Constants::SHMDATA</font>[i] == shm[i]);
- }
-
- <font color=red>/*
- Look back at the server. After filling the region, it will
- attempt to acquire the lock on 'synch'. It will wait there
- until we release() the semaphore. That will allow it to remove
- the pool and cleanup. We can simply exit once we perform the
- release. (Ok, a free() of the region would probably be polite...)
- */</font>
- if (synch.release () == -1)
- {
- ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>(%P) client synch.release</font>"), 1);
- }
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>System V Semaphores not available on this platform.\n</font>"),100);
+}
+#else <font color=red>// ACE_LACKS_SYSV_SHMEM</font>
+int
+main (int, char *[])
+{
+ <font color=red>/*
+ Use the same pool name used by the server when we create our
+ Allocator. This assures us that we don't create a whole new
+ pool.
+ */</font>
+ Allocator allocator (<font color=#008888>Constants::PoolName</font>);
+
+ <font color=red>/*
+ You can put anything in the memory pool. Not just the
+ character array we want. The find() method till, therefore,
+ return a void* that we will have to cast.
+ */</font>
+ void *region;
+
+ <font color=red>/*
+ We use find() to locate a named region in the pool. This is
+ the counterpart to bind() used in the server.
+ Here, we go try to find the region that the server has created
+ and filled with data. If there was a problem getting the pool
+ or finding the region, we'll get back -1 from find().
+ */</font>
+ if (allocator.pool ().find (<font color=#008888>Constants::RegionName</font>,region) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>Cannot find the name '%s'\n</font>",
+ <font color=#008888>Constants::RegionName</font>),
+ 100);
+
+ <font color=red>/*
+ Since find() returns us a void*, we cast it here to the char*
+ that we want.
+ */</font>
+ char *shm = (char *) region;
+
+ ACE_DEBUG ((LM_INFO,
+ "<font color=green>Shared memory is at 0x%x\n</font>",
+ shm));
+
+ <font color=red>/*
+ The same pair of semaphores as used by the server are created
+ here. We probably don't need the CREATE flag since the server
+ should have already done that. There may be some very small
+ windows, however, where the server would have created the
+ memory pool but not yet gotten to the semaphores.
+ */</font>
+ ACE_SV_Semaphore_Complex mutex;
+ ACE_ASSERT (mutex.open (<font color=#008888>Constants::SEM_KEY_1</font>,
+ <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>,
+ 0) != -1);
+
+ ACE_SV_Semaphore_Complex synch;
+ ACE_ASSERT (synch.open (<font color=#008888>Constants::SEM_KEY_2</font>,
+ <font color=#008888>ACE_SV_Semaphore_Complex::ACE_CREATE</font>,
+ 0) != -1);
+
+ <font color=red>/*
+ It doesn't matter if we created 'mutex' or if the server did.
+ In either case, it was created in a locked state and we will
+ block here until somebody unlocks it. In our scenario, that
+ will have to be the server.
+ */</font>
+ if (mutex.acquire () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P) client mutex.acquire</font>"),
+ 1);
+
+ <font color=red>/*
+ Now that we know it is safe to access the data, we'll run
+ through and make sure that it contains what we think the server
+ supplied.
+ */</font>
+ for (int i = 0; i &lt; <font color=#008888>Constants::SHMSZ</font>; i++)
+ ACE_ASSERT (<font color=#008888>Constants::SHMDATA</font>[i] == shm[i]);
+
+ <font color=red>/*
+ Look back at the server. After filling the region, it will
+ attempt to acquire the lock on 'synch'. It will wait there
+ until we release() the semaphore. That will allow it to remove
+ the pool and cleanup. We can simply exit once we perform the
+ release. (Ok, a free() of the region would probably be polite...)
+ */</font>
+ if (synch.release () == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "<font color=green>(%P) client synch.release</font>"),
+ 1);
- return 0;
+ return 0;
}
<font color=red>/*
@@ -127,6 +139,8 @@ template class ACE_Read_Guard&lt;ACE_SV_Semaphore_Simple>;
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Write_Guard&lt;ACE_SV_Semaphore_Simple>
<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Read_Guard&lt;ACE_SV_Semaphore_Simple>
<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</font>
+
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/021/page04.html b/docs/tutorials/021/page04.html
index cc6d3c0fa17..a65916da86d 100644
--- a/docs/tutorials/021/page04.html
+++ b/docs/tutorials/021/page04.html
@@ -19,7 +19,8 @@
The Allocator class is just a thin wrapper around
ACE_Malloc&lt;&gt; that moves some of the details out of the
application logic.
-<hr><PRE>
+<hr>
+<PRE>
<font color=red>// $Id$</font>
@@ -29,32 +30,35 @@
<font color=red>// Everything else we need is in this one header</font>
<font color=blue>#include</font> "<font color=green>ace/Malloc.h</font>"
+<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+
<font color=red>/*
With this we will abstract away some of the details of the memory
pool. Note that we don't treat this as a singleton because an
application may need more than one pool. Each would have a
different name and be used for different purposes.
*/</font>
+
class Allocator
{
public:
- <font color=red>// The pool name will be used to create a unique semaphore to</font>
- <font color=red>// keep this pool separate from others.</font>
- Allocator( const char * _name = "<font color=green>MemoryPool</font>" );
- ~Allocator(void);
+ <font color=red>// The pool name will be used to create a unique semaphore to</font>
+ <font color=red>// keep this pool separate from others.</font>
+ Allocator (const char * _name = "<font color=green>MemoryPool</font>");
+ ~Allocator (void);
- typedef ACE_Malloc&lt;ACE_MMAP_Memory_Pool, ACE_SV_Semaphore_Simple> pool_t;
+ typedef ACE_Malloc&lt;ACE_MMAP_Memory_Pool, ACE_SV_Semaphore_Simple> pool_t;
- <font color=red>// Provide an accessor to the pool. This will also allocate the</font>
- <font color=red>// pool when first invoked.</font>
- pool_t & pool(void);
+ <font color=red>// Provide an accessor to the pool. This will also allocate the</font>
+ <font color=red>// pool when first invoked.</font>
+ pool_t &pool (void);
protected:
- <font color=red>// The name we gave to the pool</font>
- char * name_;
+ <font color=red>// The name we gave to the pool</font>
+ char *name_;
- pool_t * pool_;
+ pool_t *pool_;
};
<font color=red>/*
@@ -64,25 +68,26 @@ protected:
class Constants
{
public:
- <font color=red>// The semaphore keys are needed for the two semaphores that</font>
- <font color=red>// synch access to the shared memory area.</font>
- static const int SEM_KEY_1;
- static const int SEM_KEY_2;
-
- <font color=red>// How big the pool will be and what we'll put into it. A real</font>
- <font color=red>// app wouldn't need SHMDATA of course.</font>
- static const int SHMSZ;
- static const char * SHMDATA;
-
- <font color=red>// The name assigned to the memory pool by the server is needed</font>
- <font color=red>// by the client. Without it, the pool cannot be found.</font>
- <font color=red>// Likewise, the name the server will bind() to the region of the </font>
- <font color=red>// pool must be available to the client.</font>
- static const char * PoolName;
- static const char * RegionName;
+ <font color=red>// The semaphore keys are needed for the two semaphores that</font>
+ <font color=red>// synch access to the shared memory area.</font>
+ static const int SEM_KEY_1;
+ static const int SEM_KEY_2;
+
+ <font color=red>// How big the pool will be and what we'll put into it. A real</font>
+ <font color=red>// app wouldn't need SHMDATA of course.</font>
+ static const int SHMSZ;
+ static const char *SHMDATA;
+
+ <font color=red>// The name assigned to the memory pool by the server is needed</font>
+ <font color=red>// by the client. Without it, the pool cannot be found.</font>
+ <font color=red>// Likewise, the name the server will bind() to the region of the </font>
+ <font color=red>// pool must be available to the client.</font>
+ static const char *PoolName;
+ static const char *RegionName;
};
-<font color=blue>#endif</font>
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
+<font color=blue>#endif</font> <font color=red>/* MPOOL_H */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/021/page05.html b/docs/tutorials/021/page05.html
index 6e238fcc85b..c5fbcdde621 100644
--- a/docs/tutorials/021/page05.html
+++ b/docs/tutorials/021/page05.html
@@ -19,12 +19,15 @@
The Allocator class is just a thin wrapper around
ACE_Malloc&lt;&gt; that moves some of the details out of the
application logic.
-<hr><PRE>
+<hr>
+<PRE>
<font color=red>// $Id$ </font>
<font color=blue>#include</font> "<font color=green>mpool.h</font>"
+<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_SYSV_SHMEM</font>)
+
<font color=red>/*
Set the values of all of the constants. This guarantees that client
and server don't get confused.
@@ -43,29 +46,25 @@ const char * <font color=#008888>Constants::RegionName</font> = "<font color=gre
has dynamically allocated it. The pool_ is set to NULL & will be
allocated by the accessor.
*/</font>
-<font color=#008888>Allocator::Allocator</font>( const char * _name )
- : name_(<font color=#008888>ACE_OS::strdup</font>(_name)),
- pool_(0)
+<font color=#008888>Allocator::Allocator</font> (const char *_name)
+ : name_ (<font color=#008888>ACE_OS::strdup</font> (_name)),
+ pool_ (0)
{
- if( ! name_ )
- {
- ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p</font>",
- "<font color=green><font color=#008888>Allocator::Allocator</font> cannot strdup pool name</font>" ));
- }
+ if (name_ == 0)
+ ACE_ERROR ((LM_ERROR, "<font color=green>(%P) %p</font>",
+ "<font color=green><font color=#008888>Allocator::Allocator</font> cannot strdup pool name</font>"));
}
-<font color=#008888>Allocator::~Allocator</font>(void)
+<font color=#008888>Allocator::~Allocator</font> (void)
{
- <font color=red>/*
- strdup() uses malloc(), so we must use free() to clean up.
- */</font>
- if( name_ )
- {
- free(name_);
- }
-
- <font color=red>// delete doesn't really care if you give it a NULL pointer.</font>
- delete pool_;
+ <font color=red>/*
+ strdup() uses malloc(), so we must use free() to clean up.
+ */</font>
+ if (name_)
+ <font color=#008888>ACE_OS::free</font> (name_);
+
+ <font color=red>// delete doesn't really care if you give it a NULL pointer.</font>
+ delete pool_;
}
<font color=red>/*
@@ -77,15 +76,17 @@ const char * <font color=#008888>Constants::RegionName</font> = "<font color=gre
Singleton because we want to have multiple Allocator instances. The
Singleton techniques can be used though.
*/</font>
-<font color=#008888>Allocator::pool_t</font> & Allocator::pool(void)
+
+<font color=#008888>Allocator::pool_t</font> &
+<font color=#008888>Allocator::pool</font> (void)
{
- if( ! pool_ )
- {
- pool_ = new pool_t( name_ );
- }
+ if (pool_ == 0)
+ pool_ = new pool_t (name_);
- return *pool_;
+ return *pool_;
}
+
+<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_SYSV_SHMEM */</font>
</PRE>
<P><HR WIDTH="100%">
<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER>
diff --git a/docs/tutorials/Makefile b/docs/tutorials/Makefile
index 60f324b146e..6174987d31b 100644
--- a/docs/tutorials/Makefile
+++ b/docs/tutorials/Makefile
@@ -1,7 +1,7 @@
# $Id$
-all clean realclean : #
+all clean realclean UNSHAR SHAR HTML : #
for i in * ; do \
[ -f $$i/Makefile ] || continue ; \
( cd $$i ; $(MAKE) $@ ) ; \