diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-07-01 16:18:56 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-07-01 16:18:56 +0000 |
commit | 6803d545979635f9fc0fb817b1e0841e69a96472 (patch) | |
tree | 74eb2aa0844bc54028da8dc9704fb6eac45322c0 /docs/tutorials/018 | |
parent | c0cc5f64b0e435e8603e6a47161d166e4140a49d (diff) | |
download | ATCD-TAO-1_1_18.tar.gz |
This commit was manufactured by cvs2svn to create tag 'TAO-1_1_18'.TAO-1_1_18
Diffstat (limited to 'docs/tutorials/018')
-rw-r--r-- | docs/tutorials/018/018.dsp | 116 | ||||
-rw-r--r-- | docs/tutorials/018/Makefile | 77 | ||||
-rw-r--r-- | docs/tutorials/018/Mutex_i.h | 17 | ||||
-rw-r--r-- | docs/tutorials/018/Test_T.cpp | 196 | ||||
-rw-r--r-- | docs/tutorials/018/Test_T.h | 80 | ||||
-rw-r--r-- | docs/tutorials/018/Token_i.h | 20 | ||||
-rw-r--r-- | docs/tutorials/018/combine.shar | 440 | ||||
-rw-r--r-- | docs/tutorials/018/output | 33 | ||||
-rw-r--r-- | docs/tutorials/018/page01.html | 70 | ||||
-rw-r--r-- | docs/tutorials/018/page02.html | 61 | ||||
-rw-r--r-- | docs/tutorials/018/page03.html | 125 | ||||
-rw-r--r-- | docs/tutorials/018/page04.html | 229 | ||||
-rw-r--r-- | docs/tutorials/018/page05.html | 66 | ||||
-rw-r--r-- | docs/tutorials/018/page06.html | 81 | ||||
-rw-r--r-- | docs/tutorials/018/page07.html | 32 | ||||
-rw-r--r-- | docs/tutorials/018/token.cpp | 32 |
16 files changed, 0 insertions, 1675 deletions
diff --git a/docs/tutorials/018/018.dsp b/docs/tutorials/018/018.dsp deleted file mode 100644 index cf22bcbfaba..00000000000 --- a/docs/tutorials/018/018.dsp +++ /dev/null @@ -1,116 +0,0 @@ -# Microsoft Developer Studio Project File - Name="018" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=018 - 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 "018.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 "018.mak" CFG="018 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "018 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "018 - 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)" == "018 - 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)" == "018 - 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:"token.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "018 - Win32 Release"
-# Name "018 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\Test_T.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\token.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\Mutex_i.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Test_T.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Token_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/018/Makefile b/docs/tutorials/018/Makefile deleted file mode 100644 index 97bcfde576f..00000000000 --- a/docs/tutorials/018/Makefile +++ /dev/null @@ -1,77 +0,0 @@ - -# $Id$ - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = token - -FILES = - -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/018/Mutex_i.h b/docs/tutorials/018/Mutex_i.h deleted file mode 100644 index f360c446679..00000000000 --- a/docs/tutorials/018/Mutex_i.h +++ /dev/null @@ -1,17 +0,0 @@ -// $Id$ - -#ifndef MUTEX_I_H -#define MUTEX_I_H - -#include "Test_T.h" - -/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */ -class Mutex : public Test_T<ACE_Mutex> -{ -public: - Mutex (void) : Test_T<ACE_Mutex> ("Mutex") {} -}; - -#endif /* MUTEX_I_H */ diff --git a/docs/tutorials/018/Test_T.cpp b/docs/tutorials/018/Test_T.cpp deleted file mode 100644 index 086ffcdfcdd..00000000000 --- a/docs/tutorials/018/Test_T.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// $Id$ - -/* This is something new... Since we're included by the header, we - have to provide a sentry to protect against recursive inclusion. - */ -#ifndef TEST_T_C -#define TEST_T_C - -// Get our definition -#include "Test_T.h" - -// We'll hard-code the thread count. Mucking around with that isn't -// really the point of the exercise today... -#define TEST_THREAD_COUNT 5 - -/* Construction time... - Initialize the baseclass, the name and the barrier. Since the - client will probably invoke run() next, we go ahead an announce our - creation to make the output more readable. - */ -template <class MUTEX> -Test_T<MUTEX>::Test_T (const char *name) - : ACE_Task<ACE_MT_SYNCH>(), - name_ (name), - barrier_ (TEST_THREAD_COUNT) -{ - ACE_DEBUG ((LM_INFO, - "(%P|%t|%T)\tTest_T (%s) created\n", - name)); -} - -/* Activate the threads and create some test data... - */ -template <class MUTEX> int -Test_T<MUTEX>::run (void) -{ - // Try to activate the set of threads that will test the mutex - if (this->open () == -1) - return -1; - - // Create a set of messages. I chose twice the thread count so that - // we can see how they get distributed. - for (int i = 0; i < TEST_THREAD_COUNT*2; ++i) - { - // A message block big enough for a simple message. - ACE_Message_Block *message; - - ACE_NEW_RETURN (message, - ACE_Message_Block (64), - -1); - - // Put some text into the message block so that we can know - // what's going on when we get to svc() - sprintf (message->wr_ptr (), - "Message Number %d", - i); - message->wr_ptr (ACE_OS::strlen (message->rd_ptr ()) + 1); - - // Send the message to the thread pool - if (this->send (message) == -1) - break; - } - - // Send a hangup to the thread pool so that we can exit. - if (this->send () == -1) - return -1; - - // Wait for all of the threads to exit and then return to the client. - return this->wait (); -} - -/* Send a message to the thread pool - */ -template <class MUTEX> int -Test_T<MUTEX>::send (ACE_Message_Block *message) -{ - // If no message was provided, create a hangup message. - if (message == 0) - { - ACE_Message_Block::ACE_Message_Type mb_hangup = - ACE_Message_Block::MB_HANGUP ; - - ACE_NEW_RETURN (message, - ACE_Message_Block (0, mb_hangup), - -1); - } - - // Use the duplicate() method when sending the message. For this - // simple application, that may be overkill but it's a good habit. - // duplicate() will increment the reference count so that each user - // of the message can release() it when done. The last user to call - // release() will cause the data to be deleted. - if (this->putq (message->duplicate ()) == -1) - { - // Error? release() the message block and return failure. - message->release (); - return -1; - } - - // release() the data to prevent memory leaks. - message->release(); - - return 0; -} - -/* A farily typical open(). Just activate the set of threads and return. - */ -template <class MUTEX> int -Test_T<MUTEX>::open (void *arg) -{ - ACE_UNUSED_ARG(arg); - return this->activate (THR_NEW_LWP, - TEST_THREAD_COUNT); -} - -/* svc() is also fairly typical. The new part is the use of the guard - to simulate protection of shared resources. - */ -template <class MUTEX> int -Test_T<MUTEX>::svc (void) -{ - // Keep a simple thread identifier. We could always use the - // thread id but this is a nice, simple number. - int my_number = ++thread_num_; - - ACE_DEBUG ((LM_INFO, - "%d (%P|%t|%T)\tTest_T::svc() Entry\n", - my_number)); - - // Wait for all of threads to get started so that they all have a - // fair shot at the message queue. Comment this out and see how the - // behaviour changes. Does it surprise you? - barrier_.wait (); - - ACE_Message_Block *message; - int mcount = 0; - - // This would usually be an almost-infinite loop. Instead, I've - // governed it so that no single thread can get more than "thread - // count" number of messages. You'll see that with ACE_Mutex, this - // is just about the only way to keep the first thread from getting - // all the action. Ths is obviously just for sake of the test since - // you don't want your real-world app to exit after a fixed number - // of messages! - while (mcount < TEST_THREAD_COUNT) - { - // Get a message. Since the message queue is already - // thread-safe we don't have to guard it. In fact, moving the - // guard up above getq() will decrease your parallelization. - if (getq (message) == -1) - break; - - // Now we pretend that there are shared resources required to - // process the data. We grab the mutex through the guard and - // "do work". In a real application, you'll want to keep these - // critical sections as small as possible since they will reduce - // the usefulness of multi-threading. - guard_t guard (mutex_); - - // Increase our message count for the debug output and the - // governor. - ++mcount; - - // Check for a hangup request... Notice the use of release() - // again to prevent leaks - if (message->msg_type () == ACE_Message_Block::MB_HANGUP) - { - message->release (); - break; - } - - // Display the message so that we can see if things are working - // the way we want. - ACE_DEBUG ((LM_INFO, - "%d (%P|%t|%T)\tTest_T::svc() received message #%d (%s)\n", - my_number, - mcount, - message->rd_ptr ())); - - // Pretend that the work takes some time to complete. Remember, - // we're holding that lock during this time! - ACE_OS::sleep (1); - - // No leaks... - message->release (); - } - - // Send a hangup to the other threads in the pool. If we don't do - // this then wait() will never exit since all of the other threads - // are still blocked on getq(). - this->send (); - - return 0; -}; - -#endif /* TEST_T_C */ diff --git a/docs/tutorials/018/Test_T.h b/docs/tutorials/018/Test_T.h deleted file mode 100644 index 2dee0e7f9ed..00000000000 --- a/docs/tutorials/018/Test_T.h +++ /dev/null @@ -1,80 +0,0 @@ -// $Id$ - -#ifndef TEST_T_H -#define TEST_T_H - -#include "ace/Task.h" - -/* We'll create a simple ACE_Task derivative for testing a couple of - different locking mechanisms. We've hidden the open() method to - force our client into using the run() method instead. - - The naming convention *_T is fairly typical for ACE. The _T suffix - on the object name (and it's source files) indicates that this is a - templated class. Generally, there is a non-templated class defined - also such as foobar.h that would be included instead of foobar_T.h. - */ - -template <class MUTEX> -class Test_T : public ACE_Task<ACE_MT_SYNCH> -{ -public: - // Allow our derivative to name the class so that we can tell the - // user what's going on as we test the lock. - Test_T (const char *name); - - // This will run the entire test. open() will be called to activate - // the task's threads. We then add a number of messages to the - // queue for svc() to process. - int run (void); - -protected: - - // Activate a few threads - int open (void *arg = 0); - - // Read some things from the message queue and exercise the lock. - int svc (void); - - // Send a message block to svc(). If _message is 0 then send a - // shutdown request (e.g., MB_HANGUP) - int send (ACE_Message_Block * message = 0); - - // The object's name. Typically provided by a derivative. - const char *name_; - - // We want to barrier the svc() methods to give all of the threads a - // fair chance - ACE_Barrier barrier_; - - // As each thread enters svc() it will increment this. While we - // have a thread id available to us, I wanted a simple value to - // display in debug messages. - ACE_Atomic_Op<ACE_Mutex,int> thread_num_; - - // Set our mutex type based on the template parameter. We then - // build a guard type based on that type. - typedef MUTEX mutex_t; - typedef ACE_Guard<mutex_t> guard_t; - - // Our mutex. We'll use this in svc() to protect imaginary shared - // resources. - mutex_t mutex_; -}; - -/* Although different compilers differ in their details, almost all of - them require that you provide the definition of the templated - object along with the declaration. With any luck, this will change - someday & we'll have smaller object files. Until then, the lines - below will take care of you. - */ - -#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) -#include "Test_T.cpp" -#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ - -#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) -#pragma implementation ("Test_T.cpp") -#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ - -#endif /* TEST_T_H */ diff --git a/docs/tutorials/018/Token_i.h b/docs/tutorials/018/Token_i.h deleted file mode 100644 index d07fe366a51..00000000000 --- a/docs/tutorials/018/Token_i.h +++ /dev/null @@ -1,20 +0,0 @@ -// $Id$ - -#ifndef TOKEN_I_H -#define TOKEN_I_H - -#include "Test_T.h" - -// Go get ace/Token.h so that we know what an ACE_Token is. -#include "ace/Token.h" - -/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */ -class Token : public Test_T<ACE_Token> -{ -public: - Token (void): Test_T<ACE_Token> ("Token") {} -}; - -#endif /* TOKEN_I_H */ diff --git a/docs/tutorials/018/combine.shar b/docs/tutorials/018/combine.shar deleted file mode 100644 index a653d49c3ce..00000000000 --- a/docs/tutorials/018/combine.shar +++ /dev/null @@ -1,440 +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 2000-03-19 15:00 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/home/jcej/projects/ACE_wrappers/docs/tutorials/018'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 416 -rw-rw-r-- hdr -# 64 -rw-rw-r-- bodies -# 2586 -rw-rw-r-- page01.pre -# 430 -rw-rw-r-- page02.pre -# 1279 -rw-rw-r-- page03.pre -# 688 -rw-rw-r-- page04.pre -# 259 -rw-rw-r-- page05.pre -# 1519 -rw-rw-r-- page06.pre -# 476 -rw-rw-r-- page07.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 _sh00359; 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 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> -X -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> -X -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> -X -<P> -<HR WIDTH="100%"> -SHAR_EOF - $shar_touch -am 03191459100 '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' -66dbcd27e23cdcc9c230089e9c289bcb hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 416 -eq "$shar_count" || - $echo 'hdr:' 'original size' '416,' '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 -token.cpp -Test_T.h -Test_T.cpp -Token_i.h Mutex_i.h -output -SHAR_EOF - $shar_touch -am 1114165298 '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' -22e70b25b6f23655b44d31fcf1a669f8 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 64 -eq "$shar_count" || - $echo 'bodies:' 'original size' '64,' '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 -Welcome to Tutorial 18! -<P> -We've seen various ACE methods for synchronization in this and other -tutorial sections. Something we haven't yet seen is the ACE_Token. -ACE_Token has a really cool thing: it behaves in a FIFO manner. -<P> -Why is that cool? -<P> -In the other tutorials, you may have found that one thread will end up -with all of the work. Even though other threads are available, the OS -scheduling and lock management just causes it to happen. With -ACE_Token, the threads are queued up on the token and served in a -traditional first-in-first-out manner. -<P> -Why is FIFO important? -<P> -Well, if your app is running in a bunch of threads and each is doing -the same thing on the local host then FIFO may not be important. -However, take the case where each thread is connected to a remote -system. Let's say you have a dozen threads in your app and each is -connected to a different remote system. Each of the threads will be -given a block of data which will be passed to the remote for some -intense calculation. If you use the FIFO then you'll spread the work -more-or-less evenly between the remote peers. If you use the -traditional mutex then one peer may get the lion's share of the work. -<P> -It gets down to a personal decision based on the application's needs. -Consider your application, examine its behavior & decide for yourself -if you want to spread the work evenly or if it's OK to let some -threads work harder than others. -<P> -Kirthika's abstract: -<UL> -A token is similar to a mutex-lock, with the difference being that -the token is given to the waiting threads in a FIFO order. In the case -of the mutex-lock, any thread (depending on the OS) could acquire -the lock when its released. It internally implements a recursive mutex, -i.e. the thread that owns the mutex can reqacquire it without deadlocking. -The token also has two FIFO lists for writers and readers with writer- -acquires having a higher priority than reader-acquires. -<P> -This tutorial throws light on the differences on having a shared resource governed by -a lock and a token, both derive from a Task which simply updates a counter with the -number-of-threads value. A barrier is used for ensuring that all threads get a equal -opportunity of grabbing the token. The message queue with the message containing the -thread count moves among the threads to be obtained and read. -<P> -On obtaining the results, we conclude that on using the Token, the job to be completed -can be distributed evenly among available threads. This cant be guaranteed -in case of simply using the lock for synchronisation. -</ul> -SHAR_EOF - $shar_touch -am 03191459100 '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' -c2c450403d3a23fb5c1d2f1dc23a1eb4 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 2586 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '2586,' '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' && -Our main() just keeps getting simpler! I guess that's a good thing. -<P> -What we've done is create two Task-derived objects that test different -locking mechanisms. The Token object uses ACE_Token and the Mutex -object uses ACE_Mutex. When you execute the application you should -see quite a difference in thread utilization. At the end of the -tutorial I've included a link to the output of a typical run of the -application. -<HR> -SHAR_EOF - $shar_touch -am 03191459100 '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' -a36353959f7874c8e31884d2acd7eb43 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 430 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '430,' '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' && -Our Test object is a simple derivative of ACE_Task. Although we've -certainly used templates in other tutorials, this is the first time -we've created one of our own. -<P> -In a lot of ways, you can think of templates as the sophisticated -cousin of the old C-style pre-processor macros. With templates, -however, you get better type-checking and much easier debugging. There -are certainly other benefits but these are my favorites. -<P> -Our template's MUTEX parameter is used to set the mutex type -<i>mutex_t</i>. That'll be used in svc() so that we can protect -shared resources needed during the processing of data received on our -message queue. -<P> -Note at the bottom how we have to include the <i>cpp</i> file -associated with us. Most compilers have to see the definition of -templated classes along with their declaration. You might be tempted, -therefore, to just put the definitions in the header file. Resist -that temptation because templates are one of the fastest growing areas -of compilers. Including the definition like we do here leads to long -compile times and overly-large binaries. With luck, the compilers -will get smarter in the future and we won't need definition -inclusion. If you've already got them broken out then you'll save -yourself a lot of time! -<HR> -SHAR_EOF - $shar_touch -am 03191459100 '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' -68432fc61bf23fe391f4ead60fe26b17 page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 1279 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '1279,' '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' && -Our Test implementation looks much like the other ACE_Task derivatives -we've used in the past. The most obvious change is the addition of -the run() method. run() will activate the threads and put a few -messages into the queue. We could have done that in main() but it -just makes more sense here. -<P> -Notice how svc() grabs the guard after getting a message from the -queue. Since we constructed our Task baseclass with ACE_MT_SYNCH, we -know that the queue is already thread-safe. Our purpose in grabbing -the additional lock is to show how ACE_Token and ACE_Mutex behave -differently. In a real app, you'd be doing this to protect shared -resources that the threads might clobber. -<HR> -SHAR_EOF - $shar_touch -am 03191459100 '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' -51ea4870a85f49c113951fedd695e35f page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 688 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '688,' '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' && -Here we create simple derivatives of our Test templated class. Each -is parameterized with our mutex of choice and "named". Using the Test -template we're able to reuse all of the code with practially no -retyping and certainly much less chance of error! -<HR> -SHAR_EOF - $shar_touch -am 03191459100 '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' -31b8531c267e036e6f463249cd04b53a page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 259 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '259,' 'current size' "$shar_count!" - fi -fi -# ============= page06.pre ============== -if test -f 'page06.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page06.pre' '(file already exists)' -else - $echo 'x -' extracting 'page06.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page06.pre' && -That's it for the code, now let's take a quick look at some output. -The first set of output is from the Token test, the second is Mutex -test. Notice how the threads are evenly utilized in the Token test. -Each thread gets to see exactly two messages. There's also an -interesting side-effect that the messages are processed in order. (You -can't rely on that, it just happend in this particular run.) -<P> -With the Mutex test, however, we see that the first thread gets no -less than 1/2 of all messages. In fact, if we didn't have the -governor in svc() it might have gotten them all! -<P> -Why does this happen? -<P> -Primarily because of time slicing. Even though each thread takes time -to do work (1 second in our test), it can still own the timeslice when -it gets back to the mutex acquire. Since the other threads are still -switched out, the current thread regets the lock and continues. On -the other hand, the ACE_Token is very careful about the order in which -the acquisition is allowed and more evenly distributes the work. -<P> -Play around with the sleep() call in svc(). You'll find that as you -decrease it, there is more chance that even the Token test will do -most of its work in one thread. You're still at the mercy of the OS -time slicing. In reality, though, it will take a moment or two for -work to be done. The end goal isn't necessarily to distribute the -work evenly over all threads but, rather, to distribute it evenly -among <i>available</i> threads. The distinction is subtle but important. -<HR> -SHAR_EOF - $shar_touch -am 03191459100 'page06.pre' && - chmod 0664 'page06.pre' || - $echo 'restore of' 'page06.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 'page06.pre:' 'MD5 check failed' -ac415a062a971ba79a088d929dda5f36 page06.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page06.pre'`" - test 1519 -eq "$shar_count" || - $echo 'page06.pre:' 'original size' '1519,' 'current size' "$shar_count!" - fi -fi -# ============= page07.pre ============== -if test -f 'page07.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page07.pre' '(file already exists)' -else - $echo 'x -' extracting 'page07.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page07.pre' && -And now we're at the end of another Tutorial. As always, feel free to -send in questions and comments. There are certainly more -implementation possibilites and I'll gladly integrate yours into these -Tutorials. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="token.cpp">token.cpp</A> -<LI><A HREF="Test.h">Test.h</A> -<LI><A HREF="Test.cpp">Test.cpp</A> -<LI><A HREF="Token_i.h">Token_i.h</A> -<LI><A HREF="Mutex_i.h">Mutex_i.h</A> -<LI><A HREF="output">output</A> -</UL> -SHAR_EOF - $shar_touch -am 03191459100 'page07.pre' && - chmod 0664 'page07.pre' || - $echo 'restore of' 'page07.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 'page07.pre:' 'MD5 check failed' -b7e7273c9bbeec45bdf2df2e8af06323 page07.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page07.pre'`" - test 476 -eq "$shar_count" || - $echo 'page07.pre:' 'original size' '476,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh00359 -exit 0 diff --git a/docs/tutorials/018/output b/docs/tutorials/018/output deleted file mode 100644 index b292728e4d6..00000000000 --- a/docs/tutorials/018/output +++ /dev/null @@ -1,33 +0,0 @@ -(21386|1024|15:26:32.366520) Test (Token) created -1 (21386|1025|15:26:32.390340) Test::svc() Entry -2 (21386|2050|15:26:32.408330) Test::svc() Entry -3 (21386|3075|15:26:32.427363) Test::svc() Entry -4 (21386|4100|15:26:32.447285) Test::svc() Entry -5 (21386|5125|15:26:32.482479) Test::svc() Entry -1 (21386|1025|15:26:32.498583) Test::svc() received message #1 (Message Number 0) -2 (21386|2050|15:26:33.517770) Test::svc() received message #1 (Message Number 1) -3 (21386|3075|15:26:34.537701) Test::svc() received message #1 (Message Number 2) -4 (21386|4100|15:26:35.557675) Test::svc() received message #1 (Message Number 3) -5 (21386|5125|15:26:36.577650) Test::svc() received message #1 (Message Number 4) -1 (21386|1025|15:26:37.597689) Test::svc() received message #2 (Message Number 5) -2 (21386|2050|15:26:38.607689) Test::svc() received message #2 (Message Number 6) -3 (21386|3075|15:26:39.617675) Test::svc() received message #2 (Message Number 7) -4 (21386|4100|15:26:40.637653) Test::svc() received message #2 (Message Number 8) -5 (21386|5125|15:26:41.657637) Test::svc() received message #2 (Message Number 9) - -(21386|1024|15:26:42.679919) Test (Mutex) created -1 (21386|6150|15:26:42.700301) Test::svc() Entry -2 (21386|7175|15:26:42.737413) Test::svc() Entry -3 (21386|8200|15:26:42.754241) Test::svc() Entry -4 (21386|9225|15:26:42.772122) Test::svc() Entry -5 (21386|10250|15:26:42.788867) Test::svc() Entry -1 (21386|6150|15:26:42.806260) Test::svc() received message #1 (Message Number 0) -1 (21386|6150|15:26:43.807539) Test::svc() received message #2 (Message Number 5) -1 (21386|6150|15:26:44.817569) Test::svc() received message #3 (Message Number 6) -1 (21386|6150|15:26:45.827571) Test::svc() received message #4 (Message Number 7) -1 (21386|6150|15:26:46.837581) Test::svc() received message #5 (Message Number 8) -2 (21386|7175|15:26:47.847908) Test::svc() received message #1 (Message Number 1) -2 (21386|7175|15:26:48.857555) Test::svc() received message #2 (Message Number 9) -4 (21386|9225|15:26:49.867991) Test::svc() received message #1 (Message Number 3) -3 (21386|8200|15:26:50.887559) Test::svc() received message #1 (Message Number 2) -5 (21386|10250|15:26:51.898275) Test::svc() received message #1 (Message Number 4) diff --git a/docs/tutorials/018/page01.html b/docs/tutorials/018/page01.html deleted file mode 100644 index e6a3db6f086..00000000000 --- a/docs/tutorials/018/page01.html +++ /dev/null @@ -1,70 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> - -Welcome to Tutorial 18! -<P> -We've seen various ACE methods for synchronization in this and other -tutorial sections. Something we haven't yet seen is the ACE_Token. -ACE_Token has a really cool thing: it behaves in a FIFO manner. -<P> -Why is that cool? -<P> -In the other tutorials, you may have found that one thread will end up -with all of the work. Even though other threads are available, the OS -scheduling and lock management just causes it to happen. With -ACE_Token, the threads are queued up on the token and served in a -traditional first-in-first-out manner. -<P> -Why is FIFO important? -<P> -Well, if your app is running in a bunch of threads and each is doing -the same thing on the local host then FIFO may not be important. -However, take the case where each thread is connected to a remote -system. Let's say you have a dozen threads in your app and each is -connected to a different remote system. Each of the threads will be -given a block of data which will be passed to the remote for some -intense calculation. If you use the FIFO then you'll spread the work -more-or-less evenly between the remote peers. If you use the -traditional mutex then one peer may get the lion's share of the work. -<P> -It gets down to a personal decision based on the application's needs. -Consider your application, examine its behavior & decide for yourself -if you want to spread the work evenly or if it's OK to let some -threads work harder than others. -<P> -Kirthika's abstract: -<UL> -A token is similar to a mutex-lock, with the difference being that -the token is given to the waiting threads in a FIFO order. In the case -of the mutex-lock, any thread (depending on the OS) could acquire -the lock when its released. It internally implements a recursive mutex, -i.e. the thread that owns the mutex can reqacquire it without deadlocking. -The token also has two FIFO lists for writers and readers with writer- -acquires having a higher priority than reader-acquires. -<P> -This tutorial throws light on the differences on having a shared resource governed by -a lock and a token, both derive from a Task which simply updates a counter with the -number-of-threads value. A barrier is used for ensuring that all threads get a equal -opportunity of grabbing the token. The message queue with the message containing the -thread count moves among the threads to be obtained and read. -<P> -On obtaining the results, we conclude that on using the Token, the job to be completed -can be distributed evenly among available threads. This cant be guaranteed -in case of simply using the lock 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/018/page02.html b/docs/tutorials/018/page02.html deleted file mode 100644 index 84dc9c9c281..00000000000 --- a/docs/tutorials/018/page02.html +++ /dev/null @@ -1,61 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Our main() just keeps getting simpler! I guess that's a good thing. -<P> -What we've done is create two Task-derived objects that test different -locking mechanisms. The Token object uses ACE_Token and the Mutex -object uses ACE_Mutex. When you execute the application you should -see quite a difference in thread utilization. At the end of the -tutorial I've included a link to the output of a typical run of the -application. -<HR> -<PRE> - -<font color=red>// $Id$</font> - -<font color=red>// Get our two Test derivatives...</font> -<font color=blue>#include</font> "<font color=green>Token_i.h</font>" -<font color=blue>#include</font> "<font color=green>Mutex_i.h</font>" - -int main(int,char**) -{ - <font color=red>// See what an ACE_Token does for us.</font> - Token token; - token.run(); - - <font color=red>// And now the ACE_Mutex.</font> - Mutex mutex; - mutex.run(); - - return(0); -} -<font color=blue>#if defined</font> (<font color=purple>ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION</font>) -template class Test_T <ACE_Mutex>; -template class Test_T <ACE_Token>; -template class ACE_Atomic_Op <ACE_Mutex, int>; -<font color=blue>#elif defined</font> (<font color=purple>ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>instantiate</font> Test_T <ACE_Mutex> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> Test_T <ACE_Token> -<font color=blue>#pragma</font> <font color=purple>instantiate</font> ACE_Atomic_Op <ACE_Mutex, int> -<font color=blue>#endif</font> <font color=red>/* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */</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/018/page03.html b/docs/tutorials/018/page03.html deleted file mode 100644 index c11e0e5b972..00000000000 --- a/docs/tutorials/018/page03.html +++ /dev/null @@ -1,125 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Our Test object is a simple derivative of ACE_Task. Although we've -certainly used templates in other tutorials, this is the first time -we've created one of our own. -<P> -In a lot of ways, you can think of templates as the sophisticated -cousin of the old C-style pre-processor macros. With templates, -however, you get better type-checking and much easier debugging. There -are certainly other benefits but these are my favorites. -<P> -Our template's MUTEX parameter is used to set the mutex type -<i>mutex_t</i>. That'll be used in svc() so that we can protect -shared resources needed during the processing of data received on our -message queue. -<P> -Note at the bottom how we have to include the <i>cpp</i> file -associated with us. Most compilers have to see the definition of -templated classes along with their declaration. You might be tempted, -therefore, to just put the definitions in the header file. Resist -that temptation because templates are one of the fastest growing areas -of compilers. Including the definition like we do here leads to long -compile times and overly-large binaries. With luck, the compilers -will get smarter in the future and we won't need definition -inclusion. If you've already got them broken out then you'll save -yourself a lot of time! -<HR> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>TEST_T_H</font> -<font color=blue>#define</font> <font color=purple>TEST_T_H</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/Task.h">ace/Task.h</A>" - -<font color=red>/* We'll create a simple ACE_Task derivative for testing a couple of - different locking mechanisms. We've hidden the open() method to - force our client into using the run() method instead. - - The naming convention *_T is fairly typical for ACE. The _T suffix - on the object name (and it's source files) indicates that this is a - templated class. Generally, there is a non-templated class defined - also such as foobar.h that would be included instead of foobar_T.h. - */</font> - -template <class MUTEX> -class Test_T : public ACE_Task<ACE_MT_SYNCH> -{ -public: - <font color=red>// Allow our derivative to name the class so that we can tell the</font> - <font color=red>// user what's going on as we test the lock.</font> - Test_T (const char *name); - - <font color=red>// This will run the entire test. open() will be called to activate</font> - <font color=red>// the task's threads. We then add a number of messages to the</font> - <font color=red>// queue for svc() to process.</font> - int run (void); - -protected: - - <font color=red>// Activate a few threads</font> - int open (void *arg = 0); - - <font color=red>// Read some things from the message queue and exercise the lock.</font> - int svc (void); - - <font color=red>// Send a message block to svc(). If _message is 0 then send a</font> - <font color=red>// shutdown request (e.g., MB_HANGUP)</font> - int send (ACE_Message_Block * message = 0); - - <font color=red>// The object's name. Typically provided by a derivative.</font> - const char *name_; - - <font color=red>// We want to barrier the svc() methods to give all of the threads a</font> - <font color=red>// fair chance</font> - ACE_Barrier barrier_; - - <font color=red>// As each thread enters svc() it will increment this. While we</font> - <font color=red>// have a thread id available to us, I wanted a simple value to</font> - <font color=red>// display in debug messages.</font> - ACE_Atomic_Op<ACE_Mutex,int> thread_num_; - - <font color=red>// Set our mutex type based on the template parameter. We then</font> - <font color=red>// build a guard type based on that type.</font> - typedef MUTEX mutex_t; - typedef ACE_Guard<mutex_t> guard_t; - - <font color=red>// Our mutex. We'll use this in svc() to protect imaginary shared</font> - <font color=red>// resources.</font> - mutex_t mutex_; -}; - -<font color=red>/* Although different compilers differ in their details, almost all of - them require that you provide the definition of the templated - object along with the declaration. With any luck, this will change - someday & we'll have smaller object files. Until then, the lines - below will take care of you. - */</font> - -<font color=blue>#if defined</font> (<font color=purple>ACE_TEMPLATES_REQUIRE_SOURCE</font>) -<font color=blue>#include</font> "<font color=green>Test_T.cpp</font>" -<font color=blue>#endif</font> <font color=red>/* ACE_TEMPLATES_REQUIRE_SOURCE */</font> - -<font color=blue>#if defined</font> (<font color=purple>ACE_TEMPLATES_REQUIRE_PRAGMA</font>) -<font color=blue>#pragma</font> <font color=purple>implementation</font> ("<font color=green>Test_T.cpp</font>") -<font color=blue>#endif</font> <font color=red>/* ACE_TEMPLATES_REQUIRE_PRAGMA */</font> - -<font color=blue>#endif</font> <font color=red>/* TEST_T_H */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/018/page04.html b/docs/tutorials/018/page04.html deleted file mode 100644 index 809d05e06fd..00000000000 --- a/docs/tutorials/018/page04.html +++ /dev/null @@ -1,229 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Our Test implementation looks much like the other ACE_Task derivatives -we've used in the past. The most obvious change is the addition of -the run() method. run() will activate the threads and put a few -messages into the queue. We could have done that in main() but it -just makes more sense here. -<P> -Notice how svc() grabs the guard after getting a message from the -queue. Since we constructed our Task baseclass with ACE_MT_SYNCH, we -know that the queue is already thread-safe. Our purpose in grabbing -the additional lock is to show how ACE_Token and ACE_Mutex behave -differently. In a real app, you'd be doing this to protect shared -resources that the threads might clobber. -<HR> -<PRE> -<font color=red>// $Id$</font> - -<font color=red>/* This is something new... Since we're included by the header, we - have to provide a sentry to protect against recursive inclusion. - */</font> -<font color=blue>#ifndef</font> <font color=purple>TEST_T_C</font> -<font color=blue>#define</font> <font color=purple>TEST_T_C</font> - -<font color=red>// Get our definition</font> -<font color=blue>#include</font> "<font color=green>Test_T.h</font>" - -<font color=red>// We'll hard-code the thread count. Mucking around with that isn't</font> -<font color=red>// really the point of the exercise today...</font> -<font color=blue>#define</font> <font color=purple>TEST_THREAD_COUNT</font> 5 - -<font color=red>/* Construction time... - Initialize the baseclass, the name and the barrier. Since the - client will probably invoke run() next, we go ahead an announce our - creation to make the output more readable. - */</font> -template <class MUTEX> -Test_T<MUTEX>::Test_T (const char *name) - : ACE_Task<ACE_MT_SYNCH>(), - name_ (name), - barrier_ (TEST_THREAD_COUNT) -{ - ACE_DEBUG ((LM_INFO, - "<font color=green>(%P|%t|%T)\tTest_T (%s) created\n</font>", - name)); -} - -<font color=red>/* Activate the threads and create some test data... - */</font> -template <class MUTEX> int -Test_T<MUTEX>::run (void) -{ - <font color=red>// Try to activate the set of threads that will test the mutex</font> - if (this->open () == -1) - return -1; - - <font color=red>// Create a set of messages. I chose twice the thread count so that</font> - <font color=red>// we can see how they get distributed.</font> - for (int i = 0; i < TEST_THREAD_COUNT*2; ++i) - { - <font color=red>// A message block big enough for a simple message.</font> - ACE_Message_Block *message; - - ACE_NEW_RETURN (message, - ACE_Message_Block (64), - -1); - - <font color=red>// Put some text into the message block so that we can know</font> - <font color=red>// what's going on when we get to svc()</font> - sprintf (message->wr_ptr (), - "<font color=green>Message Number %d</font>", - i); - message->wr_ptr (<font color=#008888>ACE_OS::strlen</font> (message->rd_ptr ()) + 1); - - <font color=red>// Send the message to the thread pool</font> - if (this->send (message) == -1) - break; - } - - <font color=red>// Send a hangup to the thread pool so that we can exit.</font> - if (this->send () == -1) - return -1; - - <font color=red>// Wait for all of the threads to exit and then return to the client.</font> - return this->wait (); -} - -<font color=red>/* Send a message to the thread pool - */</font> -template <class MUTEX> int -Test_T<MUTEX>::send (ACE_Message_Block *message) -{ - <font color=red>// If no message was provided, create a hangup message.</font> - if (message == 0) - { - <font color=#008888>ACE_Message_Block::ACE_Message_Type</font> mb_hangup = - <font color=#008888>ACE_Message_Block::MB_HANGUP</font> ; - - ACE_NEW_RETURN (message, - ACE_Message_Block (0, mb_hangup), - -1); - } - - <font color=red>// Use the duplicate() method when sending the message. For this</font> - <font color=red>// simple application, that may be overkill but it's a good habit.</font> - <font color=red>// duplicate() will increment the reference count so that each user</font> - <font color=red>// of the message can release() it when done. The last user to call</font> - <font color=red>// release() will cause the data to be deleted.</font> - if (this->putq (message->duplicate ()) == -1) - { - <font color=red>// Error? release() the message block and return failure.</font> - message->release (); - return -1; - } - - <font color=red>// release() the data to prevent memory leaks.</font> - message->release(); - - return 0; -} - -<font color=red>/* A farily typical open(). Just activate the set of threads and return. - */</font> -template <class MUTEX> int -Test_T<MUTEX>::open (void *arg) -{ - ACE_UNUSED_ARG(arg); - return this->activate (THR_NEW_LWP, - TEST_THREAD_COUNT); -} - -<font color=red>/* svc() is also fairly typical. The new part is the use of the guard - to simulate protection of shared resources. - */</font> -template <class MUTEX> int -Test_T<MUTEX>::svc (void) -{ - <font color=red>// Keep a simple thread identifier. We could always use the</font> - <font color=red>// thread id but this is a nice, simple number.</font> - int my_number = ++thread_num_; - - ACE_DEBUG ((LM_INFO, - "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() Entry\n</font>", - my_number)); - - <font color=red>// Wait for all of threads to get started so that they all have a</font> - <font color=red>// fair shot at the message queue. Comment this out and see how the</font> - <font color=red>// behaviour changes. Does it surprise you?</font> - barrier_.wait (); - - ACE_Message_Block *message; - int mcount = 0; - - <font color=red>// This would usually be an almost-infinite loop. Instead, I've</font> - <font color=red>// governed it so that no single thread can get more than "thread</font> - <font color=red>// count" number of messages. You'll see that with ACE_Mutex, this</font> - <font color=red>// is just about the only way to keep the first thread from getting</font> - <font color=red>// all the action. Ths is obviously just for sake of the test since</font> - <font color=red>// you don't want your real-world app to exit after a fixed number</font> - <font color=red>// of messages!</font> - while (mcount < TEST_THREAD_COUNT) - { - <font color=red>// Get a message. Since the message queue is already</font> - <font color=red>// thread-safe we don't have to guard it. In fact, moving the</font> - <font color=red>// guard up above getq() will decrease your parallelization.</font> - if (getq (message) == -1) - break; - - <font color=red>// Now we pretend that there are shared resources required to</font> - <font color=red>// process the data. We grab the mutex through the guard and</font> - <font color=red>// "<font color=green>do work</font>". In a real application, you'll want to keep these</font> - <font color=red>// critical sections as small as possible since they will reduce</font> - <font color=red>// the usefulness of multi-threading.</font> - guard_t guard (mutex_); - - <font color=red>// Increase our message count for the debug output and the</font> - <font color=red>// governor.</font> - ++mcount; - - <font color=red>// Check for a hangup request... Notice the use of release()</font> - <font color=red>// again to prevent leaks</font> - if (message->msg_type () == <font color=#008888>ACE_Message_Block::MB_HANGUP</font>) - { - message->release (); - break; - } - - <font color=red>// Display the message so that we can see if things are working</font> - <font color=red>// the way we want.</font> - ACE_DEBUG ((LM_INFO, - "<font color=green>%d (%P|%t|%T)\<font color=#008888>tTest_T::svc</font>() received message #%d (%s)\n</font>", - my_number, - mcount, - message->rd_ptr ())); - - <font color=red>// Pretend that the work takes some time to complete. Remember,</font> - <font color=red>// we're holding that lock during this time!</font> - <font color=#008888>ACE_OS::sleep</font> (1); - - <font color=red>// No leaks...</font> - message->release (); - } - - <font color=red>// Send a hangup to the other threads in the pool. If we don't do</font> - <font color=red>// this then wait() will never exit since all of the other threads</font> - <font color=red>// are still blocked on getq().</font> - this->send (); - - return 0; -}; - -<font color=blue>#endif</font> <font color=red>/* TEST_T_C */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/018/page05.html b/docs/tutorials/018/page05.html deleted file mode 100644 index 5c669aa3155..00000000000 --- a/docs/tutorials/018/page05.html +++ /dev/null @@ -1,66 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -Here we create simple derivatives of our Test templated class. Each -is parameterized with our mutex of choice and "named". Using the Test -template we're able to reuse all of the code with practially no -retyping and certainly much less chance of error! -<HR> -<HR width=50%><P><center>Token_i.h</center><HR width=50%> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>TOKEN_I_H</font> -<font color=blue>#define</font> <font color=purple>TOKEN_I_H</font> - -<font color=blue>#include</font> "<font color=green>Test_T.h</font>" - -<font color=red>// Go get ace/Token.h so that we know what an ACE_Token is.</font> -<font color=blue>#include</font> "<A HREF="../../../ace/Token.h">ace/Token.h</A>" - -<font color=red>/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */</font> -class Token : public Test_T<ACE_Token> -{ -public: - Token (void): Test_T<ACE_Token> ("<font color=green>Token</font>") {} -}; - -<font color=blue>#endif</font> <font color=red>/* TOKEN_I_H */</font> -</PRE> -<HR width=50%><P><center>Mutex_i.h</center><HR width=50%> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>MUTEX_I_H</font> -<font color=blue>#define</font> <font color=purple>MUTEX_I_H</font> - -<font color=blue>#include</font> "<font color=green>Test_T.h</font>" - -<font color=red>/* Create a very simple derivative of our Test template. All we have - to do is provide our mutex choice and a name. - */</font> -class Mutex : public Test_T<ACE_Mutex> -{ -public: - Mutex (void) : Test_T<ACE_Mutex> ("<font color=green>Mutex</font>") {} -}; - -<font color=blue>#endif</font> <font color=red>/* MUTEX_I_H */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/018/page06.html b/docs/tutorials/018/page06.html deleted file mode 100644 index 8d348b2289e..00000000000 --- a/docs/tutorials/018/page06.html +++ /dev/null @@ -1,81 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -That's it for the code, now let's take a quick look at some output. -The first set of output is from the Token test, the second is Mutex -test. Notice how the threads are evenly utilized in the Token test. -Each thread gets to see exactly two messages. There's also an -interesting side-effect that the messages are processed in order. (You -can't rely on that, it just happend in this particular run.) -<P> -With the Mutex test, however, we see that the first thread gets no -less than 1/2 of all messages. In fact, if we didn't have the -governor in svc() it might have gotten them all! -<P> -Why does this happen? -<P> -Primarily because of time slicing. Even though each thread takes time -to do work (1 second in our test), it can still own the timeslice when -it gets back to the mutex acquire. Since the other threads are still -switched out, the current thread regets the lock and continues. On -the other hand, the ACE_Token is very careful about the order in which -the acquisition is allowed and more evenly distributes the work. -<P> -Play around with the sleep() call in svc(). You'll find that as you -decrease it, there is more chance that even the Token test will do -most of its work in one thread. You're still at the mercy of the OS -time slicing. In reality, though, it will take a moment or two for -work to be done. The end goal isn't necessarily to distribute the -work evenly over all threads but, rather, to distribute it evenly -among <i>available</i> threads. The distinction is subtle but important. -<HR> -<PRE> -(21386|1024|15:26:32.366520) Test (Token) created -1 (21386|1025|15:26:32.390340) <font color=#008888>Test::svc</font>() Entry -2 (21386|2050|15:26:32.408330) <font color=#008888>Test::svc</font>() Entry -3 (21386|3075|15:26:32.427363) <font color=#008888>Test::svc</font>() Entry -4 (21386|4100|15:26:32.447285) <font color=#008888>Test::svc</font>() Entry -5 (21386|5125|15:26:32.482479) <font color=#008888>Test::svc</font>() Entry -1 (21386|1025|15:26:32.498583) <font color=#008888>Test::svc</font>() received message #1 (Message Number 0) -2 (21386|2050|15:26:33.517770) <font color=#008888>Test::svc</font>() received message #1 (Message Number 1) -3 (21386|3075|15:26:34.537701) <font color=#008888>Test::svc</font>() received message #1 (Message Number 2) -4 (21386|4100|15:26:35.557675) <font color=#008888>Test::svc</font>() received message #1 (Message Number 3) -5 (21386|5125|15:26:36.577650) <font color=#008888>Test::svc</font>() received message #1 (Message Number 4) -1 (21386|1025|15:26:37.597689) <font color=#008888>Test::svc</font>() received message #2 (Message Number 5) -2 (21386|2050|15:26:38.607689) <font color=#008888>Test::svc</font>() received message #2 (Message Number 6) -3 (21386|3075|15:26:39.617675) <font color=#008888>Test::svc</font>() received message #2 (Message Number 7) -4 (21386|4100|15:26:40.637653) <font color=#008888>Test::svc</font>() received message #2 (Message Number 8) -5 (21386|5125|15:26:41.657637) <font color=#008888>Test::svc</font>() received message #2 (Message Number 9) - -(21386|1024|15:26:42.679919) Test (Mutex) created -1 (21386|6150|15:26:42.700301) <font color=#008888>Test::svc</font>() Entry -2 (21386|7175|15:26:42.737413) <font color=#008888>Test::svc</font>() Entry -3 (21386|8200|15:26:42.754241) <font color=#008888>Test::svc</font>() Entry -4 (21386|9225|15:26:42.772122) <font color=#008888>Test::svc</font>() Entry -5 (21386|10250|15:26:42.788867) <font color=#008888>Test::svc</font>() Entry -1 (21386|6150|15:26:42.806260) <font color=#008888>Test::svc</font>() received message #1 (Message Number 0) -1 (21386|6150|15:26:43.807539) <font color=#008888>Test::svc</font>() received message #2 (Message Number 5) -1 (21386|6150|15:26:44.817569) <font color=#008888>Test::svc</font>() received message #3 (Message Number 6) -1 (21386|6150|15:26:45.827571) <font color=#008888>Test::svc</font>() received message #4 (Message Number 7) -1 (21386|6150|15:26:46.837581) <font color=#008888>Test::svc</font>() received message #5 (Message Number 8) -2 (21386|7175|15:26:47.847908) <font color=#008888>Test::svc</font>() received message #1 (Message Number 1) -2 (21386|7175|15:26:48.857555) <font color=#008888>Test::svc</font>() received message #2 (Message Number 9) -4 (21386|9225|15:26:49.867991) <font color=#008888>Test::svc</font>() received message #1 (Message Number 3) -3 (21386|8200|15:26:50.887559) <font color=#008888>Test::svc</font>() received message #1 (Message Number 2) -5 (21386|10250|15:26:51.898275) <font color=#008888>Test::svc</font>() received message #1 (Message Number 4) -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page07.html">Continue This Tutorial</A>]</CENTER> - diff --git a/docs/tutorials/018/page07.html b/docs/tutorials/018/page07.html deleted file mode 100644 index 28586aea1cf..00000000000 --- a/docs/tutorials/018/page07.html +++ /dev/null @@ -1,32 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="Author" CONTENT="James CE Johnson"> - <TITLE>ACE Tutorial 018</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 018</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>The FIFO Nature of ACE_Token</FONT></B></CENTER> - -<P> -<HR WIDTH="100%"> -And now we're at the end of another Tutorial. As always, feel free to -send in questions and comments. There are certainly more -implementation possibilites and I'll gladly integrate yours into these -Tutorials. -<P> -<UL> -<LI><A HREF="Makefile">Makefile</A> -<LI><A HREF="token.cpp">token.cpp</A> -<LI><A HREF="Test.h">Test.h</A> -<LI><A HREF="Test.cpp">Test.cpp</A> -<LI><A HREF="Token_i.h">Token_i.h</A> -<LI><A HREF="Mutex_i.h">Mutex_i.h</A> -<LI><A HREF="output">output</A> -</UL> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> - diff --git a/docs/tutorials/018/token.cpp b/docs/tutorials/018/token.cpp deleted file mode 100644 index 040a6ead6c6..00000000000 --- a/docs/tutorials/018/token.cpp +++ /dev/null @@ -1,32 +0,0 @@ - -// $Id$ - -// Get our two Test derivatives... -#include "Token_i.h" -#include "Mutex_i.h" - -int main(int,char**) -{ - // See what an ACE_Token does for us. - Token token; - token.run(); - - // And now the ACE_Mutex. - Mutex mutex; - mutex.run(); - - return(0); -} -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class Test_T <ACE_Mutex>; -template class Test_T <ACE_Token>; -template class ACE_Atomic_Op <ACE_Mutex, int>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate Test_T <ACE_Mutex> -#pragma instantiate Test_T <ACE_Token> -#pragma instantiate ACE_Atomic_Op <ACE_Mutex, int> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ - - - - |