diff options
Diffstat (limited to 'docs/tutorials/014')
-rw-r--r-- | docs/tutorials/014/014.dsp | 112 | ||||
-rw-r--r-- | docs/tutorials/014/EndTask.h | 89 | ||||
-rw-r--r-- | docs/tutorials/014/Makefile | 77 | ||||
-rw-r--r-- | docs/tutorials/014/Task.cpp | 206 | ||||
-rw-r--r-- | docs/tutorials/014/Task.h | 59 | ||||
-rw-r--r-- | docs/tutorials/014/combine.shar | 357 | ||||
-rw-r--r-- | docs/tutorials/014/page01.html | 72 | ||||
-rw-r--r-- | docs/tutorials/014/page02.html | 83 | ||||
-rw-r--r-- | docs/tutorials/014/page03.html | 239 | ||||
-rw-r--r-- | docs/tutorials/014/page04.html | 118 | ||||
-rw-r--r-- | docs/tutorials/014/page05.html | 208 | ||||
-rw-r--r-- | docs/tutorials/014/stream.cpp | 168 |
12 files changed, 0 insertions, 1788 deletions
diff --git a/docs/tutorials/014/014.dsp b/docs/tutorials/014/014.dsp deleted file mode 100644 index 0801d52285f..00000000000 --- a/docs/tutorials/014/014.dsp +++ /dev/null @@ -1,112 +0,0 @@ -# Microsoft Developer Studio Project File - Name="014" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=014 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "014.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "014.mak" CFG="014 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "014 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "014 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "014 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "014 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"stream.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "014 - Win32 Release"
-# Name "014 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\stream.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Task.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\EndTask.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Task.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/014/EndTask.h b/docs/tutorials/014/EndTask.h deleted file mode 100644 index a8bab2698b5..00000000000 --- a/docs/tutorials/014/EndTask.h +++ /dev/null @@ -1,89 +0,0 @@ -// $Id$ - -// EndTask.h -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) -// -// - -#ifndef ENDTASK_H -#define ENDTASK_H - -#include "Task.h" - -// When you setup a Stream and push your modules on, -// there are two additional modules that go unseen -// by the user. -// -// The Stream pushes on a Stream_Head in front of -// your first module, and a Stream_Tail behind your -// last module. -// -// If your put() a message to the Stream Tail, it -// assumes you did so in error. This simple EndTask -// class allows you to push a message to it and just -// have it safely Go Away. -// -// All this Task does is release the Message_Block -// and return 0. It's a suitable black-hole. - -class EndTask : public Task -{ -public: - typedef Task inherited; - - EndTask (const char *nameOfTask): inherited (nameOfTask, 0) - { - // when we get open()'d, it with 0 threads since there is actually - // no processing to do. - - ACE_DEBUG ((LM_INFO, - "(%P|%t) Line: %d, File: %s\n", - __LINE__, - __FILE__)); - } - - virtual int open (void *) - { - ACE_DEBUG ((LM_INFO, - "(%P|%t) Line: %d, File: %s\n", - __LINE__, - __FILE__)); - return 0; - } - - virtual int open (void) - { - ACE_DEBUG ((LM_INFO, - "(%P|%t) Line: %d, File: %s\n", - __LINE__, - __FILE__)); - return 0; - } - - virtual ~EndTask(void) - { - } - - virtual int put (ACE_Message_Block *message, - ACE_Time_Value *timeout) - { - ACE_DEBUG ((LM_INFO, - "(%P|%t) Line: %d, File: %s\n", - __LINE__, - __FILE__)); - ACE_UNUSED_ARG (timeout); - - // we don't have anything to do, so release() the message. - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) %s EndTask::put() -- releasing Message_Block\n", - this->nameOfTask ())); - message->release (); - return 0; - } - -}; - -#endif /* ENDTASK_H */ diff --git a/docs/tutorials/014/Makefile b/docs/tutorials/014/Makefile deleted file mode 100644 index 9ccd4e53357..00000000000 --- a/docs/tutorials/014/Makefile +++ /dev/null @@ -1,77 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = stream - -FILES = Task - -BUILD = $(VBIN) - -SRC = $(addsuffix .cpp,$(BIN)) -SRC += $(addsuffix .cpp,$(FILES)) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -rename : # - for i in *.cxx ; do \ - n=`expr "$$i" : "\(.*\).cxx"` ;\ - mv $$i $$n.cpp ;\ - done - -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb -ts2 -bl -bli0 < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - -e 's/ / /g' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - -Depend : depend - perl ../fix.Makefile - -.depend : # - touch .depend - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre > combine.shar && $(RM) hdr bodies *.pre - -UNSHAR : # - sh combine.shar - -CLEAN : realclean - $(RM) hdr bodies *.pre *.pst .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -include .depend diff --git a/docs/tutorials/014/Task.cpp b/docs/tutorials/014/Task.cpp deleted file mode 100644 index ceb587b2a4d..00000000000 --- a/docs/tutorials/014/Task.cpp +++ /dev/null @@ -1,206 +0,0 @@ - -// $Id$ - -// Task.cxx -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) -// -// - -#include <ace/Message_Block.h> - -#include "Task.h" - -Task::Task(const char * nameOfTask, - int numberOfThreads) - : d_numberOfThreads(numberOfThreads), - d_barrier(numberOfThreads) -{ - // Just initialize our name, number of threads, and barrier. - - ACE_OS::strcpy(d_nameOfTask, nameOfTask); -} - -Task::~Task(void) -{ - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::~Task() -- once per Task\n", d_nameOfTask)); -} - -int Task::open(void *arg) -{ - ACE_UNUSED_ARG(arg); - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::open() -- once per Task\n", d_nameOfTask)); - - // call ACE_Task::activate() to spawn the threads using - // our Task::svc() as the function to be run. - - // No need to use THR_DETACHED here, we're going to wait() - // for the threads to exit later. No leaks. - - return this->activate(THR_NEW_LWP, d_numberOfThreads); -} - -int Task::put(ACE_Message_Block *message, - ACE_Time_Value *timeout) -{ - // ACE_Stream uses the put() method of Tasks to send messages. - // This defaultly does nothing. Here we link our put() method - // directly to our putq() method, so that Messages put() to us - // will appear in the Message_Queue that is checked by the - // service threads. - - return this->putq(message, timeout); -} - -int Task::close(u_long flags) -{ - - // When the Stream closes the Module, the Module then close()'s the Task - // and passing a value of (1) as the flag. - - // When a service thread exits, it calls close() with a value that is not - // (1). - - // We use this fact to tell the difference between closing a service thread, - // and closing the main Task itself. - - if (flags == 1) { - - // The Module has asked to close the main Task. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::close() -- flags == 1 -- once per Task\n", d_nameOfTask)); - - // We create a Message_Block... - - ACE_Message_Block *hangupBlock = new ACE_Message_Block(); - - // And make it of the type MB_HANGUP. - - hangupBlock->msg_type(ACE_Message_Block::MB_HANGUP); - - // We then send this Block into the Message_Queue to be seen by the - // service threads. - - // Once again we duplicate() the Block as send it off... - - if (this->putq(hangupBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::close() putq"), -1); - } - - // ..and we're free to release() our copy of it. - - hangupBlock->release(); - - // Now, all we have to do is wait() for the service threads to all - // exit. This is where using THR_DETACHED in the activate() method - // will come back to haunt you. - - // The Stream waits until this returns before attempting to remove - // the next Module/Task group in the Stream. This allows for an - // orderly shutting down of the Stream. - - return this->wait(); - - - } else { - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::close() -- flags != 1 -- once per servicing thread\n", d_nameOfTask)); - - // This is where we can clean up any mess left over by each service thread. - // In this Task, there is nothing to do. - - } - - return 0; - -} - -int Task::svc(void) -{ - - // This is the function that our service threads run once they are spawned. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- once per servicing thread\n", d_nameOfTask)); - - // First, we wait until all of our peer service threads have arrived - // at this point also. - - d_barrier.wait(); - - ACE_Message_Block *messageBlock; - - while (1) { - - // And now we loop almost infinitely. - - // getq() will block until a Message_Block is available to be read, - // or an error occurs. - - if ( this->getq(messageBlock, 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc() getq"), -1); - } - - if (messageBlock->msg_type() == ACE_Message_Block::MB_HANGUP) { - - // If the Message_Block is of type MB_HANGUP, then we're being asked - // to shut down nicely. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- HANGUP block received\n", d_nameOfTask)); - - // So, we duplicate the Block, and put it back into the Message_Queue, - // in case there are some more peer service threads still running. - - if (this->putq(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc() putq"), -1); - } - - // We release our copy of the Block. - messageBlock->release(); - - // And we break out of the nearly infinitely loop, and - // head towards close() ourselves. - break; - } - - // If we're here, then we've received a Message_Block that was - // not informing us to quit, so we're assuming it's a valid - // meaningful Block. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- Normal block received\n", d_nameOfTask)); - - // We grab the read-pointer from the Block, and display it through a DEBUG statement. - - ACE_DEBUG ((LM_DEBUG, "(%P|%t) %s Task::svc() -- %s\n", d_nameOfTask, messageBlock->rd_ptr() )); - - // We pretend that this takes to time to process the Block. - // If you're on a fast machine, you might have to raise this - // value to actually witness different threads handling - // blocks for each Task. - - ACE_OS::sleep (ACE_Time_Value (0, 250)); - - // Since we're part of a Stream, we duplicate the Block, and - // send it on to the next Task. - - if (put_next(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "Task::svc() put_next"), -1); - } - - // And then we release our copy of it. - - messageBlock->release(); - - } - - return 0; - -} - - -const char * Task::nameOfTask(void) const -{ - return d_nameOfTask; -} diff --git a/docs/tutorials/014/Task.h b/docs/tutorials/014/Task.h deleted file mode 100644 index ae02abff1b5..00000000000 --- a/docs/tutorials/014/Task.h +++ /dev/null @@ -1,59 +0,0 @@ -// $Id$ - -// Task.h -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) - -#ifndef TASK_H -#define TASK_H - -#include <ace/Task.h> -#include <ace/Synch.h> - -// Always typedef when possible. - -typedef ACE_Task<ACE_MT_SYNCH> Task_Base; - -class Task : public Task_Base -{ -public: - typedef Task_Base inherited; - // This is just good form. - - Task (const char *nameOfTask, - int numberOfThreads); - // Initialize our Task with a name, and number of threads to spawn. - - virtual ~Task (void); - - virtual int open (void *arg); - // This is provided to prevent compiler complaints about hidden - // virtual functions. - - virtual int close (u_long flags); - // This closes down the Task and all service threads. - - virtual int put (ACE_Message_Block *message, - ACE_Time_Value *timeout); - // This is the interface that ACE_Stream uses to communicate with - // our Task. - - virtual int svc (void); - // This is the actual service loop each of the service threads - // iterates through. - - const char *nameOfTask (void) const; - // Returns the name of this Task. - -private: - int d_numberOfThreads; - char d_nameOfTask[64]; - - ACE_Barrier d_barrier; - // Simple Barrier to make sure all of our service threads have - // entered their loop before accepting any messages. -}; - -#endif /* TASK_H */ diff --git a/docs/tutorials/014/combine.shar b/docs/tutorials/014/combine.shar deleted file mode 100644 index dd173fb1a79..00000000000 --- a/docs/tutorials/014/combine.shar +++ /dev/null @@ -1,357 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1999-02-10 22:17 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/014'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 414 -rw-r--r-- hdr -# 44 -rw-r--r-- bodies -# 2609 -rw-r--r-- page01.pre -# 231 -rw-r--r-- page02.pre -# 651 -rw-r--r-- page03.pre -# 439 -rw-r--r-- page04.pre -# 1079 -rw-r--r-- page05.pre -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh28285; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<HTML> -<HEAD> -X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> -X <META NAME="Author" CONTENT="Bob McWhirter"> -X <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'hdr' && - chmod 0644 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -25304aa689283dcbed9531b68e7ae2b9 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 414 -eq "$shar_count" || - $echo 'hdr:' 'original size' '414,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -Task.h -Task.cpp -EndTask.h -stream.cpp -SHAR_EOF - $shar_touch -am 1020193698 'bodies' && - chmod 0644 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -43305b4b15975a1e4cbd99b6d3592c12 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 44 -eq "$shar_count" || - $echo 'bodies:' 'original size' '44,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -X -<p><b>ACE_Stream</b> is handy when you have several <b>ACE_Task</b> objects -that you would like to link together. -X -<p>An intermediate class you we will deal with is the <b>ACE_Module</b>. -X -<p>The basic plan is to wrap your <b>Task</b> into a <b>Module</b>, push -the <b>Module</b> onto the <b>Stream</b>. Do this for each <b>Task</b>, -X and then inject <b>Message_Block</b>s into the <b>Stream</b>. -X -<p>Each <b>Task</b> then processes the <b>Message_Block</b>, and forwards -it on to the next <b>Task</b> in the <b>Stream</b>. -X -<p>If you are not already familiar with <b>Message_Block</b>s and <b>Message_Queue</b>s, -I highly suggest that you check out <A HREF="../#MQ">Tutorials 10-13</A>. -X -<p>Streams can be used for both downstream and upstream movement of messages. Used -this way mirrors closely the way System V STREAMS work. But you don't have to use them -bidirectionally. In this tutorial, we only use one direction of the Stream. Down. -X -<p>This tutorial is contributed by Bob McWhirter (bob@netwrench.com) -X -<P> -Kirthika's abstract: -<ul> -In this tutorial, an ACE_Stream has been implemented which has modules -flowing through it.(literally ;). -The chain of modules in the Stream include the Head and Tail Modules. A -Module is simply a reader-writer pair of ACE_Tasks with the writing side -acting as downstream and the reading side as upstream. Here we are only -concerned with going downstream so we install a Task into the write-side -of the module. -<P> -The task implementation makes use of flags to decide on whether to close -the main task or the service thread. The svc () method follows the -golden rule of copying message blocks before putting them on the queue -until it comes across a hang-up message. It then puts the message back -on the queue for its peers to obtain it and exits. -<P> -Any message put onto the Tail module is an error. So a customised -derivative of the Task class is created, which collects all the garbage -messages put onto the Tail. This End_Task is put into the Stream at the -start itself such that no modules whould ever follow it! -<P> -Then the other modules are pushed from the Tail-end into the Stream. -This is because we are interested in writing and not reading. -(Picture this to be a FIFO (queue) with head and tail nodes such -that the nodes are removed from the front and put into the queue from -the back) -<P> -Each module then opens up the task which spawns threads and begins to -shove messgaes down the stream. Once we have got all the messages into -the stream, our job is completed and we shut down the Stream. -<P> -A simple way to wade down the stream...;) -</ul> -SHAR_EOF - $shar_touch -am 0210221599 'page01.pre' && - chmod 0644 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -23c8c084825939056b1c9226d4ab54c1 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 2609 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '2609,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -<P> -You find pretty soon that anytime you work with ACE_Task<> you -X have to create a derivative. The Task.h header simply provides -X that derivative with the overrides we'll need in our application. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page02.pre' && - chmod 0644 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -4568ed757f3dbc1cebb7dc10d4768894 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 231 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '231,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -<P> -Before we get to main() let's take a look at the Task implementation. -X While we've overridden several methods, the real work is done in -X the close() and svc() methods. -<P> -Notice how close() figures out if it is being called by the shutdown -X of the ACE_Stream or by the exit of svc(). The magic here is -X provided by the <i>flags</i> parameter. By handling the stream -X shutdown in this way, we don't have to do anything strange in -X svc(). We also don't end up with extra hangup messages in the -X queue when the dust all settles down. -<P> -Like our other tutorials, svc() looks for a hangup and processes data. -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page03.pre' && - chmod 0644 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -5c35812c1251ef1e8214fa9d9a18d496 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 651 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '651,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -<P> -As stated in the comments below, the default action of the task at the -X stream tail is to treat any received data as an error. In our -X implementation it will often happen that data gets through to -X the tail. How, then, do we handle this without creating an -X error condition? Simple: Create a custom Task for use as the -X stream tail that doesn't consider it an error to receive data. -<P> -Read on... -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page04.pre' && - chmod 0644 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -c6eaa0dbd1216734dcf83f5283d433f3 page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 439 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '439,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -<P> -Now we come to main(). In the previous task-chain tutorial -X every thread pool had to have the same number of threads. This -X time around, we leverage the construction method of ACE_Stream -X and ACE_Module to customize the thread-pool size in each -X ACE_Task of the stream. -<P> -Remember EndTask from the previous page? We create one here and push -X it into the stream to take care of cleaning up the messages. -X Technically, we could have replaced the default Tail task -X created by the ACE framework but it seems to make more sense to -X just push our "tail" onto the stream like the other tasks. The -X caveat to this method is that you must be sure you don't push() -X any other Modules behind the EndTask! -<P> -Once the stream of modules containing tasks is all setup then we can -X put() some data into the stream for processing. The clever use -X of Task::close() makes shutting downt the stream easier than -X ever. No messing with hangup messages at the application level, -X just close() when you're done! What could be simpler? -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1012190598 'page05.pre' && - chmod 0644 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -e1c3ef1d521db6daf9e432fb5582607d page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 1079 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '1079,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh28285 -exit 0 diff --git a/docs/tutorials/014/page01.html b/docs/tutorials/014/page01.html deleted file mode 100644 index 1be24af0723..00000000000 --- a/docs/tutorials/014/page01.html +++ /dev/null @@ -1,72 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - -<p><b>ACE_Stream</b> is handy when you have several <b>ACE_Task</b> objects -that you would like to link together. - -<p>An intermediate class you we will deal with is the <b>ACE_Module</b>. - -<p>The basic plan is to wrap your <b>Task</b> into a <b>Module</b>, push -the <b>Module</b> onto the <b>Stream</b>. Do this for each <b>Task</b>, - and then inject <b>Message_Block</b>s into the <b>Stream</b>. - -<p>Each <b>Task</b> then processes the <b>Message_Block</b>, and forwards -it on to the next <b>Task</b> in the <b>Stream</b>. - -<p>If you are not already familiar with <b>Message_Block</b>s and <b>Message_Queue</b>s, -I highly suggest that you check out <A HREF="../#MQ">Tutorials 10-13</A>. - -<p>Streams can be used for both downstream and upstream movement of messages. Used -this way mirrors closely the way System V STREAMS work. But you don't have to use them -bidirectionally. In this tutorial, we only use one direction of the Stream. Down. - -<p>This tutorial is contributed by Bob McWhirter (bob@netwrench.com) - -<P> -Kirthika's abstract: -<ul> -In this tutorial, an ACE_Stream has been implemented which has modules -flowing through it.(literally ;). -The chain of modules in the Stream include the Head and Tail Modules. A -Module is simply a reader-writer pair of ACE_Tasks with the writing side -acting as downstream and the reading side as upstream. Here we are only -concerned with going downstream so we install a Task into the write-side -of the module. -<P> -The task implementation makes use of flags to decide on whether to close -the main task or the service thread. The svc () method follows the -golden rule of copying message blocks before putting them on the queue -until it comes across a hang-up message. It then puts the message back -on the queue for its peers to obtain it and exits. -<P> -Any message put onto the Tail module is an error. So a customised -derivative of the Task class is created, which collects all the garbage -messages put onto the Tail. This End_Task is put into the Stream at the -start itself such that no modules whould ever follow it! -<P> -Then the other modules are pushed from the Tail-end into the Stream. -This is because we are interested in writing and not reading. -(Picture this to be a FIFO (queue) with head and tail nodes such -that the nodes are removed from the front and put into the queue from -the back) -<P> -Each module then opens up the task which spawns threads and begins to -shove messgaes down the stream. Once we have got all the messages into -the stream, our job is completed and we shut down the Stream. -<P> -A simple way to wade down the stream...;) -</ul> -<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/014/page02.html b/docs/tutorials/014/page02.html deleted file mode 100644 index 72259699d29..00000000000 --- a/docs/tutorials/014/page02.html +++ /dev/null @@ -1,83 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -You find pretty soon that anytime you work with ACE_Task<> you - have to create a derivative. The Task.h header simply provides - that derivative with the overrides we'll need in our application. -<P> -<HR WIDTH="100%"> -<PRE> -<font color=red>// $Id$</font> - -<font color=red>// Task.h</font> -<font color=red>//</font> -<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=blue>#ifndef</font> <font color=purple>TASK_H</font> -<font color=blue>#define</font> <font color=purple>TASK_H</font> - -<font color=blue>#include</font> <ace/Task.h> -<font color=blue>#include</font> <ace/Synch.h> - -<font color=red>// Always typedef when possible.</font> - -typedef ACE_Task<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, and number of threads to spawn.</font> - - virtual ~Task (void); - - 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); - <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 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 threads</font> - <font color=red>// iterates through.</font> - - 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 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> -</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/page03.html b/docs/tutorials/014/page03.html deleted file mode 100644 index d2acd95ca70..00000000000 --- a/docs/tutorials/014/page03.html +++ /dev/null @@ -1,239 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -Before we get to main() let's take a look at the Task implementation. - While we've overridden several methods, the real work is done in - the close() and svc() methods. -<P> -Notice how close() figures out if it is being called by the shutdown - of the ACE_Stream or by the exit of svc(). The magic here is - provided by the <i>flags</i> parameter. By handling the stream - shutdown in this way, we don't have to do anything strange in - svc(). We also don't end up with extra hangup messages in the - queue when the dust all settles down. -<P> -Like our other tutorials, svc() looks for a hangup and processes data. -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// Task.cxx</font> -<font color=red>//</font> -<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>#include</font> <ace/Message_Block.h> - -<font color=blue>#include</font> "<font color=green>Task.h</font>" - -<font color=#008888>Task::Task</font>(const char * nameOfTask, - int numberOfThreads) - : d_numberOfThreads(numberOfThreads), - d_barrier(numberOfThreads) -{ - <font color=red>// Just initialize our name, number of threads, and barrier.</font> - - <font color=#008888>ACE_OS::strcpy</font>(d_nameOfTask, nameOfTask); -} - -<font color=#008888>Task::~Task</font>(void) -{ - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::~Task</font>() -- once per Task\n</font>", d_nameOfTask)); -} - -int <font color=#008888>Task::open</font>(void *arg) -{ - ACE_UNUSED_ARG(arg); - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::open</font>() -- once per Task\n</font>", d_nameOfTask)); - - <font color=red>// call <font color=#008888>ACE_Task::activate</font>() to spawn the threads using</font> - <font color=red>// our <font color=#008888>Task::svc</font>() as the function to be run.</font> - - <font color=red>// No need to use THR_DETACHED here, we're going to wait()</font> - <font color=red>// for the threads to exit later. No leaks.</font> - - return this->activate(THR_NEW_LWP, d_numberOfThreads); -} - -int <font color=#008888>Task::put</font>(ACE_Message_Block *message, - ACE_Time_Value *timeout) -{ - <font color=red>// ACE_Stream uses the put() method of Tasks to send messages.</font> - <font color=red>// This defaultly does nothing. Here we link our put() method</font> - <font color=red>// directly to our putq() method, so that Messages put() to us</font> - <font color=red>// will appear in the Message_Queue that is checked by the</font> - <font color=red>// service threads.</font> - - return this->putq(message, timeout); -} - -int <font color=#008888>Task::close</font>(u_long flags) -{ - - <font color=red>// When the Stream closes the Module, the Module then close()'s the Task</font> - <font color=red>// and passing a value of (1) as the flag.</font> - - <font color=red>// When a service thread exits, it calls close() with a value that is not</font> - <font color=red>// (1).</font> - - <font color=red>// We use this fact to tell the difference between closing a service thread,</font> - <font color=red>// and closing the main Task itself.</font> - - if (flags == 1) { - - <font color=red>// The Module has asked to close the main Task.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::close</font>() -- flags == 1 -- once per Task\n</font>", d_nameOfTask)); - - <font color=red>// We create a Message_Block...</font> - - ACE_Message_Block *hangupBlock = new ACE_Message_Block(); - - <font color=red>// And make it of the type MB_HANGUP.</font> - - hangupBlock->msg_type(<font color=#008888>ACE_Message_Block::MB_HANGUP</font>); - - <font color=red>// We then send this Block into the Message_Queue to be seen by the</font> - <font color=red>// service threads.</font> - - <font color=red>// Once again we duplicate() the Block as send it off...</font> - - if (this->putq(hangupBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::close</font>() putq</font>"), -1); - } - - <font color=red>// ..and we're free to release() our copy of it.</font> - - hangupBlock->release(); - - <font color=red>// Now, all we have to do is wait() for the service threads to all</font> - <font color=red>// exit. This is where using THR_DETACHED in the activate() method</font> - <font color=red>// will come back to haunt you.</font> - - <font color=red>// The Stream waits until this returns before attempting to remove</font> - <font color=red>// the next Module/Task group in the Stream. This allows for an</font> - <font color=red>// orderly shutting down of the Stream.</font> - - return this->wait(); - - - } else { - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::close</font>() -- flags != 1 -- once per servicing thread\n</font>", d_nameOfTask)); - - <font color=red>// This is where we can clean up any mess left over by each service thread.</font> - <font color=red>// In this Task, there is nothing to do.</font> - - } - - return 0; - -} - -int <font color=#008888>Task::svc</font>(void) -{ - - <font color=red>// This is the function that our service threads run once they are spawned.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- once per servicing thread\n</font>", d_nameOfTask)); - - <font color=red>// First, we wait until all of our peer service threads have arrived</font> - <font color=red>// at this point also.</font> - - d_barrier.wait(); - - ACE_Message_Block *messageBlock; - - while (1) { - - <font color=red>// And now we loop almost infinitely.</font> - - <font color=red>// getq() will block until a Message_Block is available to be read,</font> - <font color=red>// or an error occurs.</font> - - if ( this->getq(messageBlock, 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::svc</font>() getq</font>"), -1); - } - - if (messageBlock->msg_type() == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>) { - - <font color=red>// If the Message_Block is of type MB_HANGUP, then we're being asked</font> - <font color=red>// to shut down nicely.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- HANGUP block received\n</font>", d_nameOfTask)); - - <font color=red>// So, we duplicate the Block, and put it back into the Message_Queue,</font> - <font color=red>// in case there are some more peer service threads still running.</font> - - if (this->putq(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::svc</font>() putq</font>"), -1); - } - - <font color=red>// We release our copy of the Block.</font> - messageBlock->release(); - - <font color=red>// And we break out of the nearly infinitely loop, and</font> - <font color=red>// head towards close() ourselves.</font> - break; - } - - <font color=red>// If we're here, then we've received a Message_Block that was</font> - <font color=red>// not informing us to quit, so we're assuming it's a valid</font> - <font color=red>// meaningful Block.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- Normal block received\n</font>", d_nameOfTask)); - - <font color=red>// We grab the read-pointer from the Block, and display it through a DEBUG statement.</font> - - ACE_DEBUG ((LM_DEBUG, "<font color=green>(%P|%t) %s <font color=#008888>Task::svc</font>() -- %s\n</font>", d_nameOfTask, messageBlock->rd_ptr() )); - - <font color=red>// We pretend that this takes to time to process the Block.</font> - <font color=red>// If you're on a fast machine, you might have to raise this</font> - <font color=red>// value to actually witness different threads handling</font> - <font color=red>// blocks for each Task.</font> - - <font color=#008888>ACE_OS::sleep</font> (ACE_Time_Value (0, 250)); - - <font color=red>// Since we're part of a Stream, we duplicate the Block, and</font> - <font color=red>// send it on to the next Task.</font> - - if (put_next(messageBlock->duplicate()) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green><font color=#008888>Task::svc</font>() put_next</font>"), -1); - } - - <font color=red>// And then we release our copy of it.</font> - - messageBlock->release(); - - } - - return 0; - -} - - -const char * <font color=#008888>Task::nameOfTask</font>(void) const -{ - return d_nameOfTask; -} -</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/014/page04.html b/docs/tutorials/014/page04.html deleted file mode 100644 index 76c784b780a..00000000000 --- a/docs/tutorials/014/page04.html +++ /dev/null @@ -1,118 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -As stated in the comments below, the default action of the task at the - stream tail is to treat any received data as an error. In our - implementation it will often happen that data gets through to - the tail. How, then, do we handle this without creating an - error condition? Simple: Create a custom Task for use as the - stream tail that doesn't consider it an error to receive data. -<P> -Read on... -<P> -<HR WIDTH="100%"> -<PRE> -<font color=red>// $Id$</font> - -<font color=red>// EndTask.h</font> -<font color=red>//</font> -<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>ENDTASK_H</font> -<font color=blue>#define</font> <font color=purple>ENDTASK_H</font> - -<font color=blue>#include</font> "<font color=green>Task.h</font>" - -<font color=red>// When you setup a Stream and push your modules on,</font> -<font color=red>// there are two additional modules that go unseen</font> -<font color=red>// by the user.</font> -<font color=red>//</font> -<font color=red>// The Stream pushes on a Stream_Head in front of</font> -<font color=red>// your first module, and a Stream_Tail behind your</font> -<font color=red>// last module.</font> -<font color=red>//</font> -<font color=red>// If your put() a message to the Stream Tail, it</font> -<font color=red>// assumes you did so in error. This simple EndTask</font> -<font color=red>// class allows you to push a message to it and just</font> -<font color=red>// have it safely Go Away.</font> -<font color=red>//</font> -<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 since there is actually</font> - <font color=red>// no processing to do.</font> - - ACE_DEBUG ((LM_INFO, - "<font color=green>(%P|%t) Line: %d, File: %s\n</font>", - __LINE__, - __FILE__)); - } - - virtual int open (void *) - { - ACE_DEBUG ((LM_INFO, - "<font color=green>(%P|%t) Line: %d, File: %s\n</font>", - __LINE__, - __FILE__)); - return 0; - } - - virtual int open (void) - { - 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) - { - 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> -</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 deleted file mode 100644 index ca647ed5e20..00000000000 --- a/docs/tutorials/014/page05.html +++ /dev/null @@ -1,208 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="Bob McWhirter"> - <TITLE>ACE Tutorial 014</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 014</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>ACE_Stream Tutorial, Of Sorts</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -<P> -Now we come to main(). In the previous task-chain tutorial - every thread pool had to have the same number of threads. This - time around, we leverage the construction method of ACE_Stream - and ACE_Module to customize the thread-pool size in each - ACE_Task of the stream. -<P> -Remember EndTask from the previous page? We create one here and push - it into the stream to take care of cleaning up the messages. - Technically, we could have replaced the default Tail task - created by the ACE framework but it seems to make more sense to - just push our "tail" onto the stream like the other tasks. The - caveat to this method is that you must be sure you don't push() - any other Modules behind the EndTask! -<P> -Once the stream of modules containing tasks is all setup then we can - put() some data into the stream for processing. The clever use - of Task::close() makes shutting downt the stream easier than - ever. No messing with hangup messages at the application level, - just close() when you're done! What could be simpler? -<P> -<HR WIDTH="100%"> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// stream.cxx</font> -<font color=red>//</font> -<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>#include</font> "<font color=green>Task.h</font>" -<font color=blue>#include</font> "<font color=green>EndTask.h</font>" -<font color=red>// This is our specialized ACE_Task.</font> - -<font color=blue>#include</font> <ace/Module.h> -<font color=blue>#include</font> <ace/Stream.h> -<font color=blue>#include</font> <ace/streams.h> -<font color=red>// These are the neccessary ACE headers.</font> - - -typedef ACE_Module<ACE_MT_SYNCH> Module; -typedef ACE_Stream<ACE_MT_SYNCH> Stream; -<font color=red>// Just to avoid a lot of typing, typedefs</font> -<font color=red>// are generally a good idea.</font> - -int main(int argc, char *argv[]) -{ - int numberOfMessages = argc > 1 ? <font color=#008888>ACE_OS::atoi</font>(argv[1]) : 3; - <font color=red>// unless otherwise specified, just send three messages</font> - <font color=red>// down the stream.</font> - - Stream theStream; - <font color=red>// the ACE_Stream itself.</font> - - <font color=red>// Now, we instantiate 4 different Tasks. These do not</font> - <font color=red>// need to be all the same class, but they do need to</font> - <font color=red>// all derrive from the same flavor of ACE_Task.</font> - <font color=red>//</font> - <font color=red>// Also, we instantiate a fifth end-cap Task to clean</font> - <font color=red>// up Message_Blocks as they reach the end.</font> - - Task *taskOne; - Task *taskTwo; - Task *taskThree; - Task *taskFour; - Task *taskEnd; - - <font color=red>// Out Task's take two arguments: a name, and the number</font> - <font color=red>// of threads to dedicate to the task.</font> - - taskOne = new Task("<font color=green>Task No. 1</font>", 1); - taskTwo = new Task("<font color=green>Task No. 2</font>", 3); - taskThree = new Task("<font color=green>Task No. 3</font>", 7); - taskFour = new Task("<font color=green>Task No. 4</font>", 1); - - <font color=red>// Our EndTask only takes 1 argument, as it actually</font> - <font color=red>// doesn't spawn any threads for processing.</font> - - taskEnd = new EndTask("<font color=green>End Task</font>"); - - Module *moduleOne; - Module *moduleTwo; - Module *moduleThree; - Module *moduleFour; - Module *moduleEnd; - - <font color=red>// ACE_Stream accepts ACE_Modules, which are simply a pair of</font> - <font color=red>// ACE_Tasks. One is dedicated for writing, while the other</font> - <font color=red>// is dedicated to reading. Think of the writing side as</font> - <font color=red>// downstream, and the reading side as upstream.</font> - <font color=red>//</font> - <font color=red>// We're only working with a unidirection Stream today,</font> - <font color=red>// so we'll only actually install a Task into the write</font> - <font color=red>// side of the module, effectively downstream.</font> - - moduleOne = new Module("<font color=green>Module No. 1</font>", taskOne); - moduleTwo = new Module("<font color=green>Module No. 2</font>", taskTwo); - moduleThree = new Module("<font color=green>Module No. 3</font>", taskThree); - moduleFour = new Module("<font color=green>Module No. 4</font>", taskFour); - moduleEnd = new Module("<font color=green>Module End</font>", taskEnd); - - <font color=red>// Now we push the Modules onto the Stream.</font> - <font color=red>// Pushing adds the module to the head, or</font> - <font color=red>// otherwise prepends it to whatever modules</font> - <font color=red>// are already installed.</font> - - <font color=red>// So, you need to push() the modules on -backwards-</font> - <font color=red>// from our viewpoint.</font> - - if (theStream.push(moduleEnd) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - if (theStream.push(moduleFour) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - <font color=red>// As we push a Module onto the Stream, it gets opened.</font> - <font color=red>// When a Module open()s, it opens the Tasks that it contains.</font> - <font color=red>//</font> - <font color=red>// Since we cannot provide an argument to this embedded</font> - <font color=red>// call to open(), we supplied specified the number of</font> - <font color=red>// threads in the constructor of our Tasks.</font> - - if (theStream.push(moduleThree) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - if (theStream.push(moduleTwo) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - if (theStream.push(moduleOne) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>push</font>"), -1); - } - - <font color=red>// Now that the Modules are open, the Tasks threads should</font> - <font color=red>// be launching and entering their svc() loop, so we send</font> - <font color=red>// some messages down the Stream.</font> - - int sent = 1; - - ACE_Message_Block *message; - - while (sent <= numberOfMessages) { - - <font color=red>// First, create ourselves a Message_Block.</font> - <font color=red>// see Tutorials 10-13 for more information</font> - <font color=red>// about Message_Blocks and Message_Queues.</font> - - message = new ACE_Message_Block(128); - - <font color=red>// Now, we grab the write-pointer from the Block,</font> - <font color=red>// and sprintf() our text into it.</font> - - <font color=#008888>ACE_OS::sprintf</font>(message->wr_ptr(), "<font color=green>Message No. %d</font>", sent); - - <font color=red>// All we have to do now is drop the Message_Block</font> - <font color=red>// into the Stream.</font> - - <font color=red>// It is always a good idea to duplicate() a Message_Block</font> - <font color=red>// when you put it into any Message_Queue, as then</font> - <font color=red>// you can always be allowed to release() your copy</font> - <font color=red>// without worry.</font> - - if (theStream.put(message->duplicate(), 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>put</font>"), -1); - } - - message->release(); - ++sent; - } - - <font color=red>// Now that we've sent our Message_Blocks, close down</font> - <font color=red>// the Stream.</font> - <font color=red>//</font> - <font color=red>// The Stream will automagically delete the Modules and</font> - <font color=red>// the contained Tasks. We don't have to do that.</font> - <font color=red>//</font> - <font color=red>// This call will block (due to the way we've written our</font> - <font color=red>// Task class) until all Message_Blocks have cleared the</font> - <font color=red>// entire Stream, and all associated threads have exited.</font> - - theStream.close(); - - return 0; -} -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/014/stream.cpp b/docs/tutorials/014/stream.cpp deleted file mode 100644 index 0e2b784b2f8..00000000000 --- a/docs/tutorials/014/stream.cpp +++ /dev/null @@ -1,168 +0,0 @@ - -// $Id$ - -// stream.cxx -// -// Tutorial regarding a way to use ACE_Stream. -// -// written by bob mcwhirter (bob@netwrench.com) -// -// - -#include "Task.h" -#include "EndTask.h" -// This is our specialized ACE_Task. - -#include <ace/Module.h> -#include <ace/Stream.h> -#include <ace/streams.h> -// These are the neccessary ACE headers. - - -typedef ACE_Module<ACE_MT_SYNCH> Module; -typedef ACE_Stream<ACE_MT_SYNCH> Stream; -// Just to avoid a lot of typing, typedefs -// are generally a good idea. - -int main(int argc, char *argv[]) -{ - int numberOfMessages = argc > 1 ? ACE_OS::atoi(argv[1]) : 3; - // unless otherwise specified, just send three messages - // down the stream. - - Stream theStream; - // the ACE_Stream itself. - - // Now, we instantiate 4 different Tasks. These do not - // need to be all the same class, but they do need to - // all derrive from the same flavor of ACE_Task. - // - // Also, we instantiate a fifth end-cap Task to clean - // up Message_Blocks as they reach the end. - - Task *taskOne; - Task *taskTwo; - Task *taskThree; - Task *taskFour; - Task *taskEnd; - - // Out Task's take two arguments: a name, and the number - // of threads to dedicate to the task. - - taskOne = new Task("Task No. 1", 1); - taskTwo = new Task("Task No. 2", 3); - taskThree = new Task("Task No. 3", 7); - taskFour = new Task("Task No. 4", 1); - - // Our EndTask only takes 1 argument, as it actually - // doesn't spawn any threads for processing. - - taskEnd = new EndTask("End Task"); - - Module *moduleOne; - Module *moduleTwo; - Module *moduleThree; - Module *moduleFour; - Module *moduleEnd; - - // ACE_Stream accepts ACE_Modules, which are simply a pair of - // ACE_Tasks. One is dedicated for writing, while the other - // is dedicated to reading. Think of the writing side as - // downstream, and the reading side as upstream. - // - // We're only working with a unidirection Stream today, - // so we'll only actually install a Task into the write - // side of the module, effectively downstream. - - moduleOne = new Module("Module No. 1", taskOne); - moduleTwo = new Module("Module No. 2", taskTwo); - moduleThree = new Module("Module No. 3", taskThree); - moduleFour = new Module("Module No. 4", taskFour); - moduleEnd = new Module("Module End", taskEnd); - - // Now we push the Modules onto the Stream. - // Pushing adds the module to the head, or - // otherwise prepends it to whatever modules - // are already installed. - - // So, you need to push() the modules on -backwards- - // from our viewpoint. - - if (theStream.push(moduleEnd) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - if (theStream.push(moduleFour) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - // As we push a Module onto the Stream, it gets opened. - // When a Module open()s, it opens the Tasks that it contains. - // - // Since we cannot provide an argument to this embedded - // call to open(), we supplied specified the number of - // threads in the constructor of our Tasks. - - if (theStream.push(moduleThree) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - if (theStream.push(moduleTwo) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - if (theStream.push(moduleOne) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "push"), -1); - } - - // Now that the Modules are open, the Tasks threads should - // be launching and entering their svc() loop, so we send - // some messages down the Stream. - - int sent = 1; - - ACE_Message_Block *message; - - while (sent <= numberOfMessages) { - - // First, create ourselves a Message_Block. - // see Tutorials 10-13 for more information - // about Message_Blocks and Message_Queues. - - message = new ACE_Message_Block(128); - - // Now, we grab the write-pointer from the Block, - // and sprintf() our text into it. - - ACE_OS::sprintf(message->wr_ptr(), "Message No. %d", sent); - - // All we have to do now is drop the Message_Block - // into the Stream. - - // It is always a good idea to duplicate() a Message_Block - // when you put it into any Message_Queue, as then - // you can always be allowed to release() your copy - // without worry. - - if (theStream.put(message->duplicate(), 0) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "put"), -1); - } - - message->release(); - ++sent; - } - - // Now that we've sent our Message_Blocks, close down - // the Stream. - // - // The Stream will automagically delete the Modules and - // the contained Tasks. We don't have to do that. - // - // This call will block (due to the way we've written our - // Task class) until all Message_Blocks have cleared the - // entire Stream, and all associated threads have exited. - - theStream.close(); - - return 0; -} |