diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-08-30 22:18:03 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-08-30 22:18:03 +0000 |
commit | a479078c9f8ff4c0c17c679468298f61c19230d9 (patch) | |
tree | c185e1bc56840640bb1944f776499c6ffaa1dc0f /docs/tutorials/016 | |
parent | dd4501a0f6706b945705b7640d212ef444c3c68e (diff) | |
download | ATCD-pre_pluggable_av_merge.tar.gz |
This commit was manufactured by cvs2svn to create tagpre_pluggable_av_merge
'pre_pluggable_av_merge'.
Diffstat (limited to 'docs/tutorials/016')
-rw-r--r-- | docs/tutorials/016/016.dsp | 108 | ||||
-rw-r--r-- | docs/tutorials/016/Condition_i.cpp | 201 | ||||
-rw-r--r-- | docs/tutorials/016/Condition_i.h | 154 | ||||
-rw-r--r-- | docs/tutorials/016/Makefile | 77 | ||||
-rw-r--r-- | docs/tutorials/016/combine.shar | 385 | ||||
-rw-r--r-- | docs/tutorials/016/condition.cpp | 249 | ||||
-rw-r--r-- | docs/tutorials/016/page01.html | 84 | ||||
-rw-r--r-- | docs/tutorials/016/page02.html | 217 | ||||
-rw-r--r-- | docs/tutorials/016/page03.html | 224 | ||||
-rw-r--r-- | docs/tutorials/016/page04.html | 273 | ||||
-rw-r--r-- | docs/tutorials/016/page05.html | 31 |
11 files changed, 0 insertions, 2003 deletions
diff --git a/docs/tutorials/016/016.dsp b/docs/tutorials/016/016.dsp deleted file mode 100644 index 3adcf4cc9db..00000000000 --- a/docs/tutorials/016/016.dsp +++ /dev/null @@ -1,108 +0,0 @@ -# Microsoft Developer Studio Project File - Name="016" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=016 - 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 "016.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 "016.mak" CFG="016 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "016 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "016 - 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)" == "016 - 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)" == "016 - 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:"condition.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "016 - Win32 Release"
-# Name "016 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\condition.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\Condition_i.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\Condition_i.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/016/Condition_i.cpp b/docs/tutorials/016/Condition_i.cpp deleted file mode 100644 index d7facf62c80..00000000000 --- a/docs/tutorials/016/Condition_i.cpp +++ /dev/null @@ -1,201 +0,0 @@ - -// $Id$ - -// Get or declaration -#include "Condition_i.h" - -/* Initialize the condition variable and create the condition mutex. - Since I don't have any guarantees on the order of member variable - initialization, I have to new the condition mutex instead of - simply constructing it. - */ -Condition::Condition(value_t _value) - : value_(_value) -{ - condition_ = new condition_t( this->mutex() ); -} - -Condition::~Condition(void) -{ - // Be sure we don't have a memeory leak - delete condition_; -} - -/* The cast operator is the easiest way to return a copy of the value - 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. - */ -Condition::operator Condition::value_t (void) -{ - // Place a guard around the variable so that it won't change as - // we're copying it back to the client. - guard_t guard(mutex_); - return value(); -} - -/* Traditional prefix increment operator. - We place a guard around the operation so that we don't collide with - any other threads. After the modification, we broadcast() a - condition change to any waiting threads. You can also use signal() - but that will only tell one thread about the change. If that - thread, in turn, invokes signal() then all threads will eventually - find out. I just thought it would be easier to use broadcast() and - be done with it. - */ -Condition & Condition::operator++ (void) -{ - guard_t guard(mutex_); - - ++value(); - - condition().broadcast(); - - return *this; -} - -/* The remaining operators all follow the same pattern that we have - above. They only differ in the modification they make to the value(). - */ - -Condition & Condition::operator-- (void) -{ - guard_t guard(mutex_); - - --value(); - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator+= (int _inc) -{ - guard_t guard(mutex_); - - value() += _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator-= (int _inc) -{ - guard_t guard(mutex_); - - value() -= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator*= (int _inc) -{ - guard_t guard(mutex_); - - value() *= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator/= (int _inc) -{ - guard_t guard(mutex_); - - value() /= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator%= (int _inc) -{ - guard_t guard(mutex_); - - value() %= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & Condition::operator= ( value_t _value ) -{ - guard_t guard(mutex_); - - value() = _value; - - condition().broadcast(); - - return *this; -} - -/* Now we get into the comparison area. - Each one follows the pattern we've already established for - waiters. - */ - -/* - We begin with an equality operator that expects a function object. - In the while() test we pass a copy of the value to the function - object for evaluation. The object can then do any comparision it - wants to check for a desired condition. When the function object - returns non-zero, the condition is met and we leave. - */ -int Condition::operator== ( Condition::Compare & _compare ) -{ - guard_t guard(mutex_); - - while( ! _compare(this->value()) ) - condition().wait(); - - return 0; -} - -// As long as the variable equals _value, we wait... -int Condition::operator== ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() == _value ) - condition().wait(); - - return 0; -} - -// As long as the variable is not equal to _value, we wait... -int Condition::operator!= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() != _value ) - condition().wait(); - - return 0; -} - -// As long as the variable is less than or equal to _value, we wait... -int Condition::operator<= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() <= _value ) - condition().wait(); - - return 0; -} - -// As long as the variable is greater than or equal to _value, we wait... -int Condition::operator>= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() >= _value ) - condition().wait(); - - return 0; -} diff --git a/docs/tutorials/016/Condition_i.h b/docs/tutorials/016/Condition_i.h deleted file mode 100644 index 2cd7adb21ba..00000000000 --- a/docs/tutorials/016/Condition_i.h +++ /dev/null @@ -1,154 +0,0 @@ -// $Id$ - -#ifndef CONDITION_H -#define CONDITION_H - -#include "ace/Synch.h" - -/** A wrapper for ACE_Condition<>. When you're using an - ACE_Condition<> 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<> 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 class into a template - parameterized on the condition variable's data type if 'int' isn't - what you want. */ -class Condition -{ -public: - // From here on I'll use value_t instead of 'int' to make any - // future upgrades easier. - typedef int value_t; - - // Initialize the condition variable - Condition (value_t value = 0); - ~Condition (void); - - /* 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. */ - - // Increment & decrement - Condition &operator++ (void); - Condition &operator-- (void); - - // Increase & decrease - Condition &operator+= (int inc); - Condition &operator-= (int inc); - - // Just to be complete - Condition &operator*= (int inc); - Condition &operator/= (int inc); - Condition &operator%= (int inc); - - // Set/Reset the condition variable's value - Condition &operator= (value_t value); - - /* 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 "typical" 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; - ... - // Wait until the condition variable has the value 42 - mycondition != 42 - ... */ - - // As long as the condition variable is NOT EQUAL TO <value>, we wait - int operator!= (value_t value); - - // As long as the condition variable is EXACTLY EQUAL TO <value>, we - // wait - int operator== (value_t value); - - // As long as the condition variable is LESS THAN OR EQUAL TO - // <value>, we wait - int operator<= (value_t value); - - // As long as the condition variable is GREATER THAN OR EQUAL TO - // <value>, we wait - int operator>= (value_t value); - - // Return the value of the condition variable - operator value_t (void); - - /* 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 - Condition::Compare and overload operator()(value_t) to take - advantage of this. Have the function return non-zero when you - consider the condition to be met. */ - class Compare - { - public: - virtual int operator() (value_t value) = 0; - }; - - /* 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. */ - int operator== (Compare & compare); - -private: - // Prevent copy construction and assignment. - Condition (const Condition &condition); - Condition &operator= (const Condition &condition); - - /* Typedefs make things easier to change later. - ACE_Condition_Thread_Mutex is used as a shorthand for - ACE_Condition<ACE_Thread_Mutex> and also because it may provide - optimizations we can use. */ - typedef ACE_Thread_Mutex mutex_t; - typedef ACE_Condition_Thread_Mutex condition_t; - typedef ACE_Guard<mutex_t> guard_t; - - // The mutex that keeps the data save - mutex_t mutex_; - - // The condition mutex that makes waiting on the condition easier. - condition_t *condition_; - - // The acutal variable that embodies the condition we're waiting - // for. - value_t value_; - - // Accessors for the two mutexes. - mutex_t &mutex (void) - { - return this->mutex_; - } - - condition_t &condition (void) - { - return *this->condition_; - } - - // This particular accessor will make things much easier if we - // decide that 'int' isn't the correct datatype for value_. Note - // that we keep this private and force clients of the class to use - // the cast operator to get a copy of the value. - value_t &value (void) - { - return this->value_; - } -}; - -#endif /* CONDITION_H */ diff --git a/docs/tutorials/016/Makefile b/docs/tutorials/016/Makefile deleted file mode 100644 index f367f64df66..00000000000 --- a/docs/tutorials/016/Makefile +++ /dev/null @@ -1,77 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = condition - -FILES = Condition_i - -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/016/combine.shar b/docs/tutorials/016/combine.shar deleted file mode 100644 index 9c5c9d8c6c0..00000000000 --- a/docs/tutorials/016/combine.shar +++ /dev/null @@ -1,385 +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-14 14:20 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/016'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 422 -rw-rw-r-- hdr -# 51 -rw-rw-r-- bodies -# 2917 -rw-rw-r-- page01.pre -# 1351 -rw-rw-r-- page02.pre -# 248 -rw-rw-r-- page03.pre -# 310 -rw-rw-r-- page04.pre -# 606 -rw-rw-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 _sh31855; 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="James CE Johnson"> -X <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 1029153498 'hdr' && - chmod 0664 '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' -34600093c989939b7a2a6806f2b18f22 hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 422 -eq "$shar_count" || - $echo 'hdr:' 'original size' '422,' '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 -Condition_i.h -Condition_i.cpp -condition.cpp -SHAR_EOF - $shar_touch -am 1029153398 'bodies' && - chmod 0664 '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' -53b96616ae101b38fd1e30b2ab8707a2 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 51 -eq "$shar_count" || - $echo 'bodies:' 'original size' '51,' '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' && -The ACE framework has quite a few objects for syncronizing your -threads and even processes. We've mentioned a few in passing already: -X ACE_Thread_Mutex and ACE_Barrier for instance. -<P> -Another interesting one is the ACE_Condition template. By using an -ACE_Condition you can have your code wait for an arbitrary condition -to occur. That condition is "embodied" in a variable of your choice. -That variable can, in turn, be any data type you wish. This makes -ACE_Condition much more flexible than a simple mutex, barrier or -semaphore. -<P> -In this tutorial, I'll create a wrapper class around the ACE_Condition -and the assorted housekeeping items necessary to make it work. I'll -use a simple integer as the condition variable but keep in mind that -you can use any data type you want. -<P> -Kirthika's abstract: -<ul> -An ACE_Condition class is a synchronisation mechanism employed in -situations where one or more threads cannot access the shared resource -unless some 'condition' becomes true. The ACE_Condition is associated -with a Mutex-lock which is released before blocking internally in the -wait call. Once the blocked thread is signaled to wake up again it -internally re-acquires the lock before checking the condition. -Unless the condition is true and it has the lock, it cant go ahead. -Once the shared resource is freed, a signal is sent to the waiting -threads which can now contend for the lock and access the resource. -<P> -Pizza-delivery metaphor: (courtesy Dr.Schmidt) -<ul> -Pizza delivery boy -- thread<br> -keys to delivery van -- mutex-lock<br> -pizza ready for delivery -- condition<br> -</Ul> -Situation: <br> -<ul> -Five pizza delivery boys use the same van. While the van is -unavailable, the boys go to sleep. When the van returns and the keys -are returned, the current user of the van nudges the other sleeping boys -to wake up and fight for the keys. Once the keys are obtained and the -pizza -is ready and out of the kitchen, the boy with the pizza and the keys can -now deliver it. -</ul> -<P> -This tutorial makes use of a wrapper class around the ACE_Condition and -uses a integer value as the condition. The four kinds of condition -implemented -are: !=, >=, <=, == by using C++ operator overloading. Guards are used -within -the methods to make sure that the method is thread-safe. Once the thread -completes -its job, it broadcasts to the waiting on it. -<P> -An ACE_Task is used to stress test the various conditions. -A test object is created for each condition and the main thread waits -until the condition becomes true. For instance: <= condition: -Five threads are spwaned which in turn increment the condition -variable, which is initialised to 1 by 2. Remember that you are waiting -on -the <= condition. So once 3 threads have been thru it, the value becomes -6 -and the condition becomes true! -<P> -This simple example shows us how to program and use the Condition -variable for -synchronisation. -</ul> -SHAR_EOF - $shar_touch -am 0214140699 'page01.pre' && - chmod 0664 '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' -37032e8a180a426e2677f3c2848162bb page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 2917 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '2917,' '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' && -We'll look first at the declaration of the wrapper class. -<P> -The way you use ACE_Condition is something like this: -<UL> -<LI>First, the setup... -<UL> -<LI>Create a variable using your choice of data types -<LI>Create a mutex that will provide thread-safe access to that -variable -<LI>Create an ACE_Condition that uses the mutex -</UL> -<P> -<LI>Waiting for the condition... -<UL> -<PRE> -the_mutex.acquire(); -while( the_variable != some_desired_state_or_value ) -X the_condition.wait(); -the_mutex.release(); -</PRE> -Note that when <i>the_condition</i> is created, it must be given a -reference to the mutex. That's because the wait() method will release -the mutex before waiting and reacquire it after being signaled. -</UL> -<P> -<LI>Setting the condition... -<UL> -<PRE> -the_mutex.acquire(); -the_variable = some_new_value_or_state; -the_condition.signal() <i>OR</i> the_condition.broadcast() -</pre> -</UL> -</UL> -<P> -The problem I have is remembering to setup everything and co-ordinate -the locking, waiting and signaling. Even if I remember it all -correctly it just makes my application code more complex than it -should be. -<P> -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> -SHAR_EOF - $shar_touch -am 1029191498 'page02.pre' && - chmod 0664 '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' -d3230a58558843154d2363ce940dbb9b page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 1351 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '1351,' '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' && -Ok, now we'll take a look at the definition of the class. You already -know how to use an ACE_Condition & it's not really that difficult. -Still, imagine how much more cluttered your code would be if it had to -include the mess I've got below! -<HR> -SHAR_EOF - $shar_touch -am 1029162998 'page03.pre' && - chmod 0664 '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' -51c4ebc7f5c67e072fed8f76bd7be62d page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 248 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '248,' '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' && -We finally get to the main() application. I create a simple Task -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> -SHAR_EOF - $shar_touch -am 1029185698 'page04.pre' && - chmod 0664 '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' -a2b2c42216f88e006a18d37adcb31c1d page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 310 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '310,' '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' && -And that's all... -<P> -For general use, it would make sense to convert Condition into a -template and get rid of some of the operators that don't make sense. -Using an integer as the condition type probably isn't realistic since -you could just use a semaphore or barrier for that case. Still, the -Tutorial shows the basics and provides a foundation on which you can -create a more useful class for your application. -<P> -<UL> -<LI><A HREF="Condition_i.h">Condition_i.h</A> -<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> -SHAR_EOF - $shar_touch -am 1029192198 'page05.pre' && - chmod 0664 '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' -3926547773016bf56d809fae9170625e page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 606 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '606,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh31855 -exit 0 diff --git a/docs/tutorials/016/condition.cpp b/docs/tutorials/016/condition.cpp deleted file mode 100644 index d489ee6a355..00000000000 --- a/docs/tutorials/016/condition.cpp +++ /dev/null @@ -1,249 +0,0 @@ - -// $Id$ - -#include "Condition_i.h" -#include "ace/Task.h" - -/* In order to test our Condition we'll derive from ACE_Task<> so that - we can have several threads accessing the condition variable - together. - */ -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - // Construct the condition variable with an initial value. - Test( int _max_threads, Condition::value_t _value ); - ~Test(void); - - // Open the Task with enough threads to make a useful test. - int open(void); - -protected: - // Each thread will do work on the Condition. - int svc(void); - - // Override this method to modify the Condition in some way. - virtual void modify(void) = 0; - - // Override this to test the Condition in some way. - virtual void test(void) = 0; - - // How many threads to use in the test. This is also used in the - // modify() and test() methods of the derivatives. - int max_threads_; - - // We want to sleep for a random amount of time to simulate - // work. The seed is necessary for proper random number generation. - ACE_RANDR_TYPE seed_; - - // This is the actual condition variable set. - Condition condition_; -}; - -// Initialize the condition variable. -Test::Test( int _max_threads, Condition::value_t _value ) - : max_threads_(_max_threads), condition_(_value) -{ - ; -} - -Test::~Test(void) -{ - ; -} - -// Seed the random number generator and start the threads. -int Test::open(void) -{ - seed_ = ACE_OS::gettimeofday().usec(); - - ACE_OS::srand( seed_ ); - - return this->activate(THR_NEW_LWP, max_threads_); -} - -/* Each thread will modify the condition variable in some way and then - wait for the condition to be satisfied. The derived classes - overload modify() and test() to implement a specific test of the - Condition class. - */ -int Test::svc(void) -{ - // Take a moment before we modify the condition. This will - // cause test() in other threads to delay a bit. - int stime = ACE_OS::rand_r( seed_ ) % 5; - ACE_OS::sleep(abs(stime)+2); - - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() befor modify, condition_ is: %d\n", (int)condition_ )); - - // Change the condition variable's value - modify(); - - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() after modify, condition_ is: %d\n", (int)condition_ )); - - // Test for the condition we want - test(); - - ACE_DEBUG ((LM_INFO, "(%P|%t|%T)\tTest::svc() leaving.\n" )); - - return(0); -} - -/* Test Condition::operator!=() - The task's svc() method will increment the condition variable and - then wait until the variable's value reaches max_threads_. - */ -class Test_ne : public Test -{ -public: - // Initialize the condition variable to zero since we're counting up. - Test_ne( int _max_threads ) - : Test(_max_threads,0) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ != %d\n", max_threads_)); - } - - // Increment the variable - void modify(void) - { - ++condition_; - } - - // Wait until it equals max_threads_ - void test(void) - { - condition_ != max_threads_; - } -}; - -/* Test Condition::operator>=() - Each svc() method will decrement the condition variable and wait - until it is less than max_threads_. To do this correctly, we have - to be careful where we start the condition variable. - */ -class Test_ge : public Test -{ -public: - // For max_threads_ == 5, we will start the condition variable at - // the value 9. When the "last" thread decrements it, the value - // will be 4 which satisfies the condition. - Test_ge( int _max_threads ) - : Test(_max_threads,_max_threads*2-1) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ >= %d\n", max_threads_)); - } - - // Decrement by one... - void modify(void) - { - --condition_; - } - - // while( value >= max_threads_ ) wait(); - void test(void) - { - condition_ >= max_threads_; - } -}; - -/* Test Condition::operator<=() - This time we will increment the condition until it is greater than - max_threads_. Again, we have to be careful where we start the - value and how we increment. - */ -class Test_le : public Test -{ -public: - // I'm starting the value at 1 so that if we increment by one in - // each thread, the "last" thread (of 5) will set the value to - // 6. Since I actually increment by 2, we could start somewhat lower. - Test_le( int _max_threads ) - : Test( _max_threads, 1 ) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ <= %d\n", max_threads_)); - } - - // Try out Condition::operator+=(int) - // This will cause the third thread to satisfy the condition. - void modify(void) - { - condition_ += 2; - } - - // while( value <= max_threads_ ) wait(); - void test(void) - { - condition_ <= max_threads_; - } -}; - -/* For our final test, we'll go after Condition::operator=(Condition::Compare) - By deriving from Condition::Compare we can perform any arbitrary - test on the value of the condition variable. - */ -class Test_fo : public Test -{ -public: - // We'll be using operator*=(int) to increment the condition - // variable, so we need to start with a non-zero value. - Test_fo( int _max_threads ) - : Test( _max_threads, 1 ) - { - ACE_DEBUG ((LM_INFO, "\n(%P|%t|%T)\tTesting condition_ == FunctionObject\n" )); - } - - // Double the value for each thread that we have. - void modify(void) - { - condition_ *= 2; - } - - /* Derive our CompareFunction and provide the operator() that - performs our test. In this case, we'll compare the value to - the number 32. - */ - class CompareFunction : public Condition::Compare - { - public: - // When this returns non-zero, the condition test operator - // will unblock in each thread. - // Note that 32 was chosen because 2**5 == 32. That is, the - // fifth thread will modify() the value to 32. - int operator() ( Condition::value_t _value ) - { - return _value == 32; - } - }; - - // Create the CompareFunction and wait for the condition variable - // to reach the state we want. - void test(void) - { - CompareFunction compare; - condition_ == compare; - } -}; - -/* In main() we just instantiate each of the four test objects that we - created. After open()ing each, we wait() for it's threads to exit. - */ -int main(int, char **) -{ - Test_ne test_ne(5); - test_ne.open(); - test_ne.wait(); - - Test_ge test_ge(5); - test_ge.open(); - test_ge.wait(); - - Test_le test_le(5); - test_le.open(); - test_le.wait(); - - Test_fo test_fo(5); - test_fo.open(); - test_fo.wait(); - - return(0); -} diff --git a/docs/tutorials/016/page01.html b/docs/tutorials/016/page01.html deleted file mode 100644 index 8781d692e14..00000000000 --- a/docs/tutorials/016/page01.html +++ /dev/null @@ -1,84 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -The ACE framework has quite a few objects for syncronizing your -threads and even processes. We've mentioned a few in passing already: - ACE_Thread_Mutex and ACE_Barrier for instance. -<P> -Another interesting one is the ACE_Condition template. By using an -ACE_Condition you can have your code wait for an arbitrary condition -to occur. That condition is "embodied" in a variable of your choice. -That variable can, in turn, be any data type you wish. This makes -ACE_Condition much more flexible than a simple mutex, barrier or -semaphore. -<P> -In this tutorial, I'll create a wrapper class around the ACE_Condition -and the assorted housekeeping items necessary to make it work. I'll -use a simple integer as the condition variable but keep in mind that -you can use any data type you want. -<P> -Kirthika's abstract: -<ul> -An ACE_Condition class is a synchronisation mechanism employed in -situations where one or more threads cannot access the shared resource -unless some 'condition' becomes true. The ACE_Condition is associated -with a Mutex-lock which is released before blocking internally in the -wait call. Once the blocked thread is signaled to wake up again it -internally re-acquires the lock before checking the condition. -Unless the condition is true and it has the lock, it cant go ahead. -Once the shared resource is freed, a signal is sent to the waiting -threads which can now contend for the lock and access the resource. -<P> -Pizza-delivery metaphor: (courtesy Dr.Schmidt) -<ul> -Pizza delivery boy -- thread<br> -keys to delivery van -- mutex-lock<br> -pizza ready for delivery -- condition<br> -</Ul> -Situation: <br> -<ul> -Five pizza delivery boys use the same van. While the van is -unavailable, the boys go to sleep. When the van returns and the keys -are returned, the current user of the van nudges the other sleeping boys -to wake up and fight for the keys. Once the keys are obtained and the -pizza -is ready and out of the kitchen, the boy with the pizza and the keys can -now deliver it. -</ul> -<P> -This tutorial makes use of a wrapper class around the ACE_Condition and -uses a integer value as the condition. The four kinds of condition -implemented -are: !=, >=, <=, == by using C++ operator overloading. Guards are used -within -the methods to make sure that the method is thread-safe. Once the thread -completes -its job, it broadcasts to the waiting on it. -<P> -An ACE_Task is used to stress test the various conditions. -A test object is created for each condition and the main thread waits -until the condition becomes true. For instance: <= condition: -Five threads are spwaned which in turn increment the condition -variable, which is initialised to 1 by 2. Remember that you are waiting -on -the <= condition. So once 3 threads have been thru it, the value becomes -6 -and the condition becomes true! -<P> -This simple example shows us how to program and use the Condition -variable for -synchronisation. -</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/016/page02.html b/docs/tutorials/016/page02.html deleted file mode 100644 index 21d9b282e4c..00000000000 --- a/docs/tutorials/016/page02.html +++ /dev/null @@ -1,217 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -We'll look first at the declaration of the wrapper class. -<P> -The way you use ACE_Condition is something like this: -<UL> -<LI>First, the setup... -<UL> -<LI>Create a variable using your choice of data types -<LI>Create a mutex that will provide thread-safe access to that -variable -<LI>Create an ACE_Condition that uses the mutex -</UL> -<P> -<LI>Waiting for the condition... -<UL> -<PRE> -the_mutex.acquire(); -while( the_variable != some_desired_state_or_value ) - the_condition.wait(); -the_mutex.release(); -</PRE> -Note that when <i>the_condition</i> is created, it must be given a -reference to the mutex. That's because the wait() method will release -the mutex before waiting and reacquire it after being signaled. -</UL> -<P> -<LI>Setting the condition... -<UL> -<PRE> -the_mutex.acquire(); -the_variable = some_new_value_or_state; -the_condition.signal() <i>OR</i> the_condition.broadcast() -</pre> -</UL> -</UL> -<P> -The problem I have is remembering to setup everything and co-ordinate -the locking, waiting and signaling. Even if I remember it all -correctly it just makes my application code more complex than it -should be. -<P> -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> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>CONDITION_H</font> -<font color=blue>#define</font> <font color=purple>CONDITION_H</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/Synch.h">ace/Synch.h</A>" - -<font color=red>/** A wrapper for ACE_Condition<>. When you're using an - ACE_Condition<> 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<> 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 class 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>// 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</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>// <value>, we wait</font> - int operator<= (value_t value); - - <font color=red>// As long as the condition variable is GREATER THAN OR EQUAL TO</font> - <font color=red>// <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<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<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> -</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 deleted file mode 100644 index 4c4077a415a..00000000000 --- a/docs/tutorials/016/page03.html +++ /dev/null @@ -1,224 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Ok, now we'll take a look at the definition of the class. You already -know how to use an ACE_Condition & it's not really that difficult. -Still, imagine how much more cluttered your code would be if it had to -include the mess I've got below! -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// Get or declaration</font> -<font color=blue>#include</font> "<font color=green>Condition_i.h</font>" - -<font color=red>/* Initialize the condition variable and create the condition mutex. - Since I don't have any guarantees on the order of member variable - initialization, I have to new the condition mutex instead of - simply constructing it. - */</font> -<font color=#008888>Condition::Condition</font>(value_t _value) - : value_(_value) -{ - condition_ = new condition_t( this->mutex() ); -} - -<font color=#008888>Condition::~Condition</font>(void) -{ - <font color=red>// Be sure we don't have a memeory leak</font> - delete condition_; -} - -<font color=red>/* The cast operator is the easiest way to return a copy of the value - 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> 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> - guard_t guard(mutex_); - return value(); -} - -<font color=red>/* Traditional prefix increment operator. - We place a guard around the operation so that we don't collide with - any other threads. After the modification, we broadcast() a - condition change to any waiting threads. You can also use signal() - but that will only tell one thread about the change. If that - thread, in turn, invokes signal() then all threads will eventually - find out. I just thought it would be easier to use broadcast() and - be done with it. - */</font> -Condition & <font color=#008888>Condition::operator</font>++ (void) -{ - guard_t guard(mutex_); - - ++value(); - - condition().broadcast(); - - return *this; -} - -<font color=red>/* The remaining operators all follow the same pattern that we have - above. They only differ in the modification they make to the value(). - */</font> - -Condition & <font color=#008888>Condition::operator</font>-- (void) -{ - guard_t guard(mutex_); - - --value(); - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>+= (int _inc) -{ - guard_t guard(mutex_); - - value() += _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>-= (int _inc) -{ - guard_t guard(mutex_); - - value() -= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>*= (int _inc) -{ - guard_t guard(mutex_); - - value() *= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>/= (int _inc) -{ - guard_t guard(mutex_); - - value() /= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>%= (int _inc) -{ - guard_t guard(mutex_); - - value() %= _inc; - - condition().broadcast(); - - return *this; -} - -Condition & <font color=#008888>Condition::operator</font>= ( value_t _value ) -{ - guard_t guard(mutex_); - - value() = _value; - - condition().broadcast(); - - return *this; -} - -<font color=red>/* Now we get into the comparison area. - Each one follows the pattern we've already established for - waiters. - */</font> - -<font color=red>/* - We begin with an equality operator that expects a function object. - In the while() test we pass a copy of the value to the function - object for evaluation. The object can then do any comparision it - wants to check for a desired condition. When the function object - returns non-zero, the condition is met and we leave. - */</font> -int <font color=#008888>Condition::operator</font>== ( Condition::Compare & _compare ) -{ - guard_t guard(mutex_); - - while( ! _compare(this->value()) ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable equals _value, we wait...</font> -int <font color=#008888>Condition::operator</font>== ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() == _value ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable is not equal to _value, we wait...</font> -int <font color=#008888>Condition::operator</font>!= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() != _value ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable is less than or equal to _value, we wait...</font> -int <font color=#008888>Condition::operator</font><= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() <= _value ) - condition().wait(); - - return 0; -} - -<font color=red>// As long as the variable is greater than or equal to _value, we wait...</font> -int <font color=#008888>Condition::operator</font>>= ( value_t _value ) -{ - guard_t guard(mutex_); - - while( value() >= _value ) - condition().wait(); - - 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/016/page04.html b/docs/tutorials/016/page04.html deleted file mode 100644 index c9cc4dc6b4b..00000000000 --- a/docs/tutorials/016/page04.html +++ /dev/null @@ -1,273 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -We finally get to the main() application. I create a simple Task -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> - -<font color=red>// $Id$</font> - -<font color=blue>#include</font> "<font color=green>Condition_i.h</font>" -<font color=blue>#include</font> "<A HREF="../../../ace/Task.h">ace/Task.h</A>" - -<font color=red>/* In order to test our Condition we'll derive from ACE_Task<> so that - we can have several threads accessing the condition variable - together. - */</font> -class Test : public ACE_Task<ACE_NULL_SYNCH> -{ -public: - <font color=red>// Construct the condition variable with an initial value.</font> - Test( int _max_threads, <font color=#008888>Condition::value_t</font> _value ); - ~Test(void); - - <font color=red>// Open the Task with enough threads to make a useful test.</font> - int open(void); - -protected: - <font color=red>// Each thread will do work on the Condition.</font> - int svc(void); - - <font color=red>// Override this method to modify the Condition in some way.</font> - virtual void modify(void) = 0; - - <font color=red>// Override this to test the Condition in some way.</font> - virtual void test(void) = 0; - - <font color=red>// How many threads to use in the test. This is also used in the</font> - <font color=red>// modify() and test() methods of the derivatives.</font> - int max_threads_; - - <font color=red>// We want to sleep for a random amount of time to simulate</font> - <font color=red>// work. The seed is necessary for proper random number generation.</font> - ACE_RANDR_TYPE seed_; - - <font color=red>// This is the actual condition variable set.</font> - Condition condition_; -}; - -<font color=red>// Initialize the condition variable.</font> -<font color=#008888>Test::Test</font>( int _max_threads, Condition::value_t _value ) - : max_threads_(_max_threads), condition_(_value) -{ - ; -} - -<font color=#008888>Test::~Test</font>(void) -{ - ; -} - -<font color=red>// Seed the random number generator and start the threads.</font> -int <font color=#008888>Test::open</font>(void) -{ - seed_ = <font color=#008888>ACE_OS::gettimeofday</font>().usec(); - - <font color=#008888>ACE_OS::srand</font>( seed_ ); - - return this->activate(THR_NEW_LWP, max_threads_); -} - -<font color=red>/* Each thread will modify the condition variable in some way and then - wait for the condition to be satisfied. The derived classes - overload modify() and test() to implement a specific test of the - Condition class. - */</font> -int <font color=#008888>Test::svc</font>(void) -{ - <font color=red>// Take a moment before we modify the condition. This will</font> - <font color=red>// cause test() in other threads to delay a bit.</font> - int stime = <font color=#008888>ACE_OS::rand_r</font>( seed_ ) % 5; - <font color=#008888>ACE_OS::sleep</font>(abs(stime)+2); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() befor modify, condition_ is: %d\n</font>", (int)condition_ )); - - <font color=red>// Change the condition variable's value</font> - modify(); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() after modify, condition_ is: %d\n</font>", (int)condition_ )); - - <font color=red>// Test for the condition we want</font> - test(); - - ACE_DEBUG ((LM_INFO, "<font color=green>(%P|%t|%T)\<font color=#008888>tTest::svc</font>() leaving.\n</font>" )); - - return(0); -} - -<font color=red>/* Test <font color=#008888>Condition::operator</font>!=() - The task's svc() method will increment the condition variable and - then wait until the variable's value reaches max_threads_. - */</font> -class Test_ne : public Test -{ -public: - <font color=red>// Initialize the condition variable to zero since we're counting up.</font> - Test_ne( int _max_threads ) - : Test(_max_threads,0) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ != %d\n</font>", max_threads_)); - } - - <font color=red>// Increment the variable</font> - void modify(void) - { - ++condition_; - } - - <font color=red>// Wait until it equals max_threads_</font> - void test(void) - { - condition_ != max_threads_; - } -}; - -<font color=red>/* Test <font color=#008888>Condition::operator</font>>=() - Each svc() method will decrement the condition variable and wait - until it is less than max_threads_. To do this correctly, we have - to be careful where we start the condition variable. - */</font> -class Test_ge : public Test -{ -public: - <font color=red>// For max_threads_ == 5, we will start the condition variable at </font> - <font color=red>// the value 9. When the "<font color=green>last</font>" thread decrements it, the value</font> - <font color=red>// will be 4 which satisfies the condition.</font> - Test_ge( int _max_threads ) - : Test(_max_threads,_max_threads*2-1) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ >= %d\n</font>", max_threads_)); - } - - <font color=red>// Decrement by one...</font> - void modify(void) - { - --condition_; - } - - <font color=red>// while( value >= max_threads_ ) wait();</font> - void test(void) - { - condition_ >= max_threads_; - } -}; - -<font color=red>/* Test <font color=#008888>Condition::operator</font><=() - This time we will increment the condition until it is greater than - max_threads_. Again, we have to be careful where we start the - value and how we increment. - */</font> -class Test_le : public Test -{ -public: - <font color=red>// I'm starting the value at 1 so that if we increment by one in</font> - <font color=red>// each thread, the "<font color=green>last</font>" thread (of 5) will set the value to</font> - <font color=red>// 6. Since I actually increment by 2, we could start somewhat lower.</font> - Test_le( int _max_threads ) - : Test( _max_threads, 1 ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ <= %d\n</font>", max_threads_)); - } - - <font color=red>// Try out <font color=#008888>Condition::operator</font>+=(int)</font> - <font color=red>// This will cause the third thread to satisfy the condition.</font> - void modify(void) - { - condition_ += 2; - } - - <font color=red>// while( value <= max_threads_ ) wait();</font> - void test(void) - { - condition_ <= max_threads_; - } -}; - -<font color=red>/* For our final test, we'll go after <font color=#008888>Condition::operator</font>=(Condition::Compare) - By deriving from <font color=#008888>Condition::Compare</font> we can perform any arbitrary - test on the value of the condition variable. - */</font> -class Test_fo : public Test -{ -public: - <font color=red>// We'll be using operator*=(int) to increment the condition</font> - <font color=red>// variable, so we need to start with a non-zero value.</font> - Test_fo( int _max_threads ) - : Test( _max_threads, 1 ) - { - ACE_DEBUG ((LM_INFO, "<font color=green>\n(%P|%t|%T)\tTesting condition_ == FunctionObject\n</font>" )); - } - - <font color=red>// Double the value for each thread that we have.</font> - void modify(void) - { - condition_ *= 2; - } - - <font color=red>/* Derive our CompareFunction and provide the operator() that - performs our test. In this case, we'll compare the value to - the number 32. - */</font> - class CompareFunction : public <font color=#008888>Condition::Compare</font> - { - public: - <font color=red>// When this returns non-zero, the condition test operator</font> - <font color=red>// will unblock in each thread.</font> - <font color=red>// Note that 32 was chosen because 2**5 == 32. That is, the</font> - <font color=red>// fifth thread will modify() the value to 32.</font> - int operator() ( <font color=#008888>Condition::value_t</font> _value ) - { - return _value == 32; - } - }; - - <font color=red>// Create the CompareFunction and wait for the condition variable </font> - <font color=red>// to reach the state we want.</font> - void test(void) - { - CompareFunction compare; - condition_ == compare; - } -}; - -<font color=red>/* In main() we just instantiate each of the four test objects that we - created. After open()ing each, we wait() for it's threads to exit. - */</font> -int main(int, char **) -{ - Test_ne test_ne(5); - test_ne.open(); - test_ne.wait(); - - Test_ge test_ge(5); - test_ge.open(); - test_ge.wait(); - - Test_le test_le(5); - test_le.open(); - test_le.wait(); - - Test_fo test_fo(5); - test_fo.open(); - test_fo.wait(); - - return(0); -} -</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/016/page05.html b/docs/tutorials/016/page05.html deleted file mode 100644 index baf3eb23a4a..00000000000 --- a/docs/tutorials/016/page05.html +++ /dev/null @@ -1,31 +0,0 @@ -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 016</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 016</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Making ACE_Condition easier to use</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And that's all... -<P> -For general use, it would make sense to convert Condition into a -template and get rid of some of the operators that don't make sense. -Using an integer as the condition type probably isn't realistic since -you could just use a semaphore or barrier for that case. Still, the -Tutorial shows the basics and provides a foundation on which you can -create a more useful class for your application. -<P> -<UL> -<LI><A HREF="Condition_i.h">Condition_i.h</A> -<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%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> |