#!/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 . # 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' && X X X ACE Tutorial 014 X
ACE Tutorial 014
X
ACE_Stream Tutorial, Of Sorts
X


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

ACE_Stream is handy when you have several ACE_Task objects that you would like to link together. X

An intermediate class you we will deal with is the ACE_Module. X

The basic plan is to wrap your Task into a Module, push the Module onto the Stream. Do this for each Task, X and then inject Message_Blocks into the Stream. X

Each Task then processes the Message_Block, and forwards it on to the next Task in the Stream. X

If you are not already familiar with Message_Blocks and Message_Queues, I highly suggest that you check out Tutorials 10-13. X

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

This tutorial is contributed by Bob McWhirter (bob@netwrench.com) X

Kirthika's abstract:

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' &&

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.


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' &&

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.

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 flags 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.

Like our other tutorials, svc() looks for a hangup and processes data.


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' &&

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.

Read on...


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' &&

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.

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!

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?


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