diff options
Diffstat (limited to 'ACE/examples/APG/Processes')
-rw-r--r-- | ACE/examples/APG/Processes/.cvsignore | 8 | ||||
-rw-r--r-- | ACE/examples/APG/Processes/Makefile.am | 90 | ||||
-rw-r--r-- | ACE/examples/APG/Processes/Process_Manager_Death.cpp | 67 | ||||
-rw-r--r-- | ACE/examples/APG/Processes/Process_Manager_Spawn.cpp | 59 | ||||
-rw-r--r-- | ACE/examples/APG/Processes/Process_Mutex.cpp | 79 | ||||
-rw-r--r-- | ACE/examples/APG/Processes/Spawn.cpp | 206 | ||||
-rw-r--r-- | ACE/examples/APG/Processes/processes.mpc | 34 |
7 files changed, 543 insertions, 0 deletions
diff --git a/ACE/examples/APG/Processes/.cvsignore b/ACE/examples/APG/Processes/.cvsignore new file mode 100644 index 00000000000..187cf413af2 --- /dev/null +++ b/ACE/examples/APG/Processes/.cvsignore @@ -0,0 +1,8 @@ +Process_Manager_Death +Process_Manager_Death +Process_Manager_Spawn +Process_Manager_Spawn +Process_Mutex +Process_Mutex +Spawn +Spawn diff --git a/ACE/examples/APG/Processes/Makefile.am b/ACE/examples/APG/Processes/Makefile.am new file mode 100644 index 00000000000..5c45a506304 --- /dev/null +++ b/ACE/examples/APG/Processes/Makefile.am @@ -0,0 +1,90 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.Process_Manager_Death.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Process_Manager_Death + +Process_Manager_Death_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Process_Manager_Death_SOURCES = \ + Process_Manager_Death.cpp + +Process_Manager_Death_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Process_Manager_Spawn.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Process_Manager_Spawn + +Process_Manager_Spawn_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Process_Manager_Spawn_SOURCES = \ + Process_Manager_Spawn.cpp + +Process_Manager_Spawn_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Process_Mutex.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Process_Mutex + +Process_Mutex_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Process_Mutex_SOURCES = \ + Process_Mutex.cpp + +Process_Mutex_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Spawn.am + +if !BUILD_ACE_FOR_TAO +noinst_PROGRAMS += Spawn + +Spawn_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +Spawn_SOURCES = \ + Spawn.cpp + +Spawn_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/APG/Processes/Process_Manager_Death.cpp b/ACE/examples/APG/Processes/Process_Manager_Death.cpp new file mode 100644 index 00000000000..51a8d911458 --- /dev/null +++ b/ACE/examples/APG/Processes/Process_Manager_Death.cpp @@ -0,0 +1,67 @@ +// $Id$ + +#include "ace/Log_Msg.h" +#include "ace/Process_Manager.h" +#include "ace/Reactor.h" + +static const int NCHILDREN = 2; + +// Listing 1 code/ch10 +class DeathHandler: public ACE_Event_Handler +{ +public: + DeathHandler () : count_(0) + { + ACE_TRACE (ACE_TEXT ("DeathHandler::DeathHandler")); + } + + virtual int handle_exit (ACE_Process * process) + { + ACE_TRACE (ACE_TEXT ("DeathHandler::handle_exit")); + + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("Process %d exited with exit code %d\n"), + process->getpid (), process->return_value ())); + + if (++count_ == NCHILDREN) + ACE_Reactor::instance ()->end_reactor_event_loop (); + + return 0; + } + +private: + int count_; +}; +// Listing 1 +// Listing 0 code/ch10 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Running as a child. + return 0; + + // Instantiate a process manager with space for + // 10 processes. + ACE_Process_Manager pm (10, ACE_Reactor::instance ()); + + // Create a process termination handler. + DeathHandler handler; + + // Specify the options for the new processes to be spawned. + ACE_Process_Options options; + options.command_line (ACE_TEXT ("%s a"), argv[0]); + + // Spawn two child processes. + pid_t pids[NCHILDREN]; + pm.spawn_n (NCHILDREN, options, pids); + + // Register handler to be called when these processes exit. + for (int i = 0; i < NCHILDREN; i++) + pm.register_handler (&handler, pids[i]); + + // Run the reactor event loop waiting for events to occur. + ACE_Reactor::instance ()->run_reactor_event_loop (); + + return 0; +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/Process_Manager_Spawn.cpp b/ACE/examples/APG/Processes/Process_Manager_Spawn.cpp new file mode 100644 index 00000000000..dd61ae9bae8 --- /dev/null +++ b/ACE/examples/APG/Processes/Process_Manager_Spawn.cpp @@ -0,0 +1,59 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" +// Listing 0 code/ch10 +#include "ace/Process_Manager.h" + +static const int NCHILDREN = 2; + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Running as a child. + { + ACE_OS::sleep (10); + } + else // Running as a parent. + { + // Get the processwide process manager. + ACE_Process_Manager* pm = ACE_Process_Manager::instance (); + + // Specify the options for the new processes + // to be spawned. + ACE_Process_Options options; + options.command_line (ACE_TEXT ("%s a"), argv[0]); + + // Spawn two child processes. + pid_t pids[NCHILDREN]; + pm->spawn_n (NCHILDREN, options, pids); + + // Destroy the first child. + pm->terminate (pids[0]); + + // Wait for the child we just terminated. + ACE_exitcode status; + pm->wait (pids[0], &status); + + // Get the results of the termination. + +#if !defined(ACE_WIN32) + if (WIFSIGNALED (status) != 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%d died because of a signal ") + ACE_TEXT ("of type %d\n"), + pids[0], WTERMSIG (status))); +#else + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("The process terminated with exit code %d\n"), + status)); +#endif /*ACE_WIN32*/ + + // Wait for all (only one left) of the + // children to exit. + pm->wait (0); + } + + return 0; +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/Process_Mutex.cpp b/ACE/examples/APG/Processes/Process_Mutex.cpp new file mode 100644 index 00000000000..2afb89803b9 --- /dev/null +++ b/ACE/examples/APG/Processes/Process_Mutex.cpp @@ -0,0 +1,79 @@ +// $Id$ + +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" +#include "ace/Process.h" +#include "ace/Process_Mutex.h" + +// Listing 1 code/ch10 +class GResourceUser +{ +public: + GResourceUser (ACE_Process_Mutex &mutex) : gmutex_(mutex) + { + ACE_TRACE (ACE_TEXT ("GResourceUser::GResourceUser")); + } + + void run (void) + { + ACE_TRACE (ACE_TEXT ("GResourceUser::run")); + + int count = 0; + while (count++ < 10) + { + int result = this->gmutex_.acquire (); + ACE_ASSERT (result == 0); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P| %t) has the mutex\n"))); + + // Access Global resource + ACE_OS::sleep (1); + + result = this->gmutex_.release (); + ACE_ASSERT (result == 0); + ACE_OS::sleep (1); // Give other process a chance. + } + } + +private: + ACE_Process_Mutex &gmutex_; +}; +// Listing 1 + +// Listing 0 code/ch10 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Run as the child. + { + // Create or get the global mutex. + ACE_Process_Mutex mutex ("GlobalMutex"); + + GResourceUser acquirer (mutex); + acquirer.run (); + } + else // Run as the parent. + { + ACE_Process_Options options; + options.command_line (ACE_TEXT ("%s a"), argv[0]); + ACE_Process processa, processb; + + pid_t pida = processa.spawn (options); + pid_t pidb = processb.spawn (options); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Spawned processes; pids %d:%d\n"), + pida, pidb)); + + if (processa.wait() == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("processa wait")), -1); + + if (processb.wait() == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("processb wait")), -1); + } + + return 0; +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/Spawn.cpp b/ACE/examples/APG/Processes/Spawn.cpp new file mode 100644 index 00000000000..0776a44a8ec --- /dev/null +++ b/ACE/examples/APG/Processes/Spawn.cpp @@ -0,0 +1,206 @@ +// $Id$ + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_pwd.h" +#include "ace/os_include/os_pwd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Process.h" +#include "ace/Log_Msg.h" + +// Listing 1 code/ch10 +class Manager : public ACE_Process +{ +public: + Manager (const ACE_TCHAR* program_name) + { + ACE_TRACE ("Manager::Manager"); + ACE_OS::strcpy (programName_, program_name); + } + + int doWork (void) + { + ACE_TRACE ("Manager::doWork"); + + // Spawn the new process; prepare() hook is called first. + ACE_Process_Options options; + pid_t pid = this->spawn (options); + if (pid == ACE_INVALID_PID) + ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("spawn")), -1); + + // Wait forever for my child to exit. + if (this->wait () == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("wait")), -1); + + // Dump whatever happened. + this->dumpRun (); + return 0; + } +// Listing 1 + +private: + // Listing 3 code/ch10 + int dumpRun (void) + { + ACE_TRACE ("Manager::dumpRun"); + + if (ACE_OS::lseek (this->outputfd_, 0, SEEK_SET) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("lseek")), -1); + + char buf[1024]; + ssize_t length = 0; + + // Read the contents of the error stream written + // by the child and print it out. + while ((length = ACE_OS::read (this->outputfd_, + buf, sizeof(buf)-1)) > 0) + { + buf[length] = 0; + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%C\n"), buf)); + } + + ACE_OS::close (this->outputfd_); + return 0; + } + // Listing 3 + + // Listing 2 code/ch10 + // prepare() is inherited from ACE_Process. + int prepare (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::prepare"); + + options.command_line (ACE_TEXT ("%s 1"), this->programName_); + if (this->setStdHandles (options) == -1 || + this->setEnvVariable (options) == -1) + return -1; +#if !defined (ACE_WIN32) && !defined (ACE_LACKS_PWD_FUNCTIONS) + return this->setUserID (options); +#else + return 0; +#endif + } + + int setStdHandles (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::setStdHandles"); + + ACE_OS::unlink ("output.dat"); + this->outputfd_ = + ACE_OS::open ("output.dat", O_RDWR | O_CREAT); + return options.set_handles + (ACE_STDIN, ACE_STDOUT, this->outputfd_); + } + + int setEnvVariable (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::setEnvVariables"); + return options.setenv + (ACE_TEXT ("PRIVATE_VAR=/that/seems/to/be/it")); + } + // Listing 2 + +#if !defined (ACE_LACKS_PWD_FUNCTIONS) + // Listing 10 code/ch10 + int setUserID (ACE_Process_Options &options) + { + ACE_TRACE ("Manager::setUserID"); + passwd* pw = ACE_OS::getpwnam ("nobody"); + if (pw == 0) + return -1; + options.seteuid (pw->pw_uid); + return 0; + } + // Listing 10 +#endif /* !ACE_LACKS_PWD_FUNCTIONS */ + +private: + ACE_HANDLE outputfd_; + ACE_TCHAR programName_[256]; +}; + +// Listing 4 code/ch10 +class Slave +{ +public: + Slave () + { + ACE_TRACE ("Slave::Slave"); + } + + int doWork (void) + { + ACE_TRACE ("Slave::doWork"); + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) started at %T, parent is %d\n"), + ACE_OS::getppid ())); + this->showWho (); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) the private environment is %s\n"), + ACE_OS::getenv ("PRIVATE_VAR"))); + + ACE_TCHAR str[128]; + ACE_OS::sprintf (str, ACE_TEXT ("(%d) Enter your command\n"), + static_cast<int>(ACE_OS::getpid ())); + ACE_OS::write (ACE_STDOUT, str, ACE_OS::strlen (str)); + this->readLine (str); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P) Executed: %C\n"), + str)); + return 0; + } +// Listing 4 + + void showWho (void) + { + ACE_TRACE ("Slave::showWho"); +#if !defined (ACE_LACKS_PWD_FUNCTIONS) + passwd *pw = ::getpwuid (::geteuid ()); + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("(%P) Running this process as:%s\n"), + pw->pw_name)); +#endif + } + + ACE_TCHAR* readLine (ACE_TCHAR* str) + { + ACE_TRACE ("Slave::readLine"); + + int i = 0; + while (true) + { + ssize_t retval = ACE_OS::read (ACE_STDIN, &str[i], 1); + if (retval > 0) + { + if (str[i] == '\n') + { + str[++i] = 0; + return str; + } + i++; + } + else + return str; + } + } +}; + +// Listing 0 code/ch10 +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc > 1) // Slave mode + { + Slave s; + return s.doWork (); + } + + // Else, Master mode + Manager m (argv[0]); + return m.doWork (); +} +// Listing 0 diff --git a/ACE/examples/APG/Processes/processes.mpc b/ACE/examples/APG/Processes/processes.mpc new file mode 100644 index 00000000000..a7cb01040bb --- /dev/null +++ b/ACE/examples/APG/Processes/processes.mpc @@ -0,0 +1,34 @@ +// -*- MPC -*- +// $Id$ + +project(Process Manager Death) : aceexe { + avoids += ace_for_tao + exename = Process_Manager_Death + Source_Files { + Process_Manager_Death.cpp + } +} + +project(Process Manager Spawn) : aceexe { + avoids += ace_for_tao + exename = Process_Manager_Spawn + Source_Files { + Process_Manager_Spawn.cpp + } +} + +project(Process Mutex) : aceexe { + avoids += ace_for_tao + exename = Process_Mutex + Source_Files { + Process_Mutex.cpp + } +} + +project(Spawn) : aceexe { + avoids += ace_for_tao + exename = Spawn + Source_Files { + Spawn.cpp + } +} |