PageRenderTime 75ms CodeModel.GetById 43ms RepoModel.GetById 0ms app.codeStats 0ms

/perl/site/lib/Win32/Job.pm

https://github.com/Tailgunner/CataMooseC
Perl | 370 lines | 302 code | 67 blank | 1 comment | 13 complexity | 93f85a77d02e3c7d1659c665c550769c MD5 | raw file
  1. package Win32::Job;
  2. use strict;
  3. use base qw(DynaLoader);
  4. use vars qw($VERSION);
  5. $VERSION = '0.03';
  6. use constant WIN32s => 0;
  7. use constant WIN9X => 1;
  8. use constant WINNT => 2;
  9. require Win32 unless defined &Win32::GetOSVersion;
  10. my @ver = Win32::GetOSVersion;
  11. die "Win32::Job is not supported on $ver[0]" unless (
  12. $ver[4] == WINNT and (
  13. $ver[1] > 5 or
  14. ($ver[1] == 5 and $ver[2] > 0) or
  15. ($ver[1] == 5 and $ver[2] == 0 and $ver[3] >= 0)
  16. )
  17. );
  18. Win32::Job->bootstrap($VERSION);
  19. 1;
  20. __END__
  21. =head1 NAME
  22. Win32::Job - Run sub-processes in a "job" environment
  23. =head1 SYNOPSIS
  24. use Win32::Job;
  25. my $job = Win32::Job->new;
  26. # Run 'perl Makefile.PL' for 10 seconds
  27. $job->spawn($Config{perlpath}, "perl Makefile.PL");
  28. $job->run(10);
  29. =head1 PLATFORMS
  30. Win32::Job requires Windows 2000 or later. Windows 95, 98, NT, and Me are not
  31. supported.
  32. =head1 DESCRIPTION
  33. Windows 2000 introduced the concept of a "job": a collection of processes
  34. which can be controlled as a single unit. For example, you can reliably kill a
  35. process and all of its children by launching the process in a job, then
  36. telling Windows to kill all processes in the job. Win32::Job makes this
  37. feature available to Perl.
  38. For example, imagine you want to allow 2 minutes for a process to complete.
  39. If you have control over the child process, you can probably just run it in
  40. the background, then poll every second to see if it has finished.
  41. That's fine as long as the child process doesn't spawn any child processes.
  42. What if it does? If you wrote the child process yourself and made an effort to
  43. clean up your child processes before terminating, you don't have to worry.
  44. If not, you will leave hanging processes (called "zombie" processes in Unix).
  45. With Win32::Job, just create a new Job, then use the job to spawn the child
  46. process. All I<its> children will also be created in the new Job. When you
  47. time out, just call the job's kill() method and the entire process tree will
  48. be terminated.
  49. =head1 Using Win32::Job
  50. The following methods are available:
  51. =over 4
  52. =item 1
  53. new()
  54. new();
  55. Creates a new Job object using the Win32 API call CreateJobObject(). The job
  56. is created with a default security context, and is unnamed.
  57. Note: this method returns C<undef> if CreateJobObject() fails. Look at C<$^E>
  58. for more detailed error information.
  59. =item 2
  60. spawn()
  61. spawn($exe, $args, \%opts);
  62. Creates a new process and associates it with the Job. The process is initially
  63. suspended, and can be resumed with one of the other methods. Uses the Win32
  64. API call CreateProcess(). Returns the PID of the newly created process.
  65. Note: this method returns C<undef> if CreateProcess() fails. See C<$^E> for
  66. more detailed error information. One reason this will fail is if the calling
  67. process is itself part of a job, and the job's security context does not allow
  68. child processes to be created in a different job context than the parent.
  69. The arguments are described here:
  70. =over 4
  71. =item 1
  72. $exe
  73. The executable program to run. This may be C<undef>, in which case the first
  74. argument in $args is the program to run.
  75. If this has path information in it, it is used "as is" and passed to
  76. CreateProcess(), which interprets it as either an absolute path, or a
  77. path relative to the current drive and directory. If you did not specify an
  78. extension, ".exe" is assumed.
  79. If there are no path separators (either backslashes or forward slashes),
  80. then Win32::Job will search the current directory and your PATH, looking
  81. for the file. In addition, if you did not specify an extension, then
  82. Win32::Job checks ".exe", ".com", and ".bat" in order. If it finds a ".bat"
  83. file, Win32::Job will actually call F<cmd.exe> and prepend "cmd.exe" to the
  84. $args.
  85. For example, assuming a fairly normal PATH:
  86. spawn(q{c:\winnt\system\cmd.exe}, q{cmd /C "echo %PATH%"})
  87. exefile: c:\winnt\system\cmd.exe
  88. cmdline: cmd /C "echo %PATH%"
  89. spawn("cmd.exe", q{cmd /C "echo %PATH%"})
  90. exefile: c:\winnt\system\cmd.exe
  91. cmdline: cmd /C "echo %PATH%"
  92. =item 2
  93. $args
  94. The commandline to pass to the executable program. The first word will be
  95. C<argv[0]> to an EXE file, so you should repeat the command name in $args.
  96. For example:
  97. $job->spawn($Config{perlpath}, "perl foo.pl");
  98. In this case, the "perl" is ignored, since perl.exe doesn't use it.
  99. =item 3
  100. %opts
  101. A hash reference for advanced options. This parameter is optional.
  102. the following keys are recognized:
  103. =over 4
  104. =item cwd
  105. A string specifying the current directory of the new process.
  106. By default, the process shares the parent's current directory, C<.>.
  107. =item new_console
  108. A boolean; if true, the process is started in a new console window.
  109. By default, the process shares the parent's console. This has no effect on GUI
  110. programs which do not interact with the console.
  111. =item window_attr
  112. Either C<minimized>, which displays the new window minimized; C<maximimzed>,
  113. which shows the new window maximized; or C<hidden>, which does not display the
  114. new window.
  115. By default, the window is displayed using its application's defaults.
  116. =item new_group
  117. A boolean; if true, the process is the root of a new process group. This
  118. process group includes all descendents of the child.
  119. By default, the process is in the parent's process group (but in a new job).
  120. =item no_window
  121. A boolean; if true, the process is run without a console window. This flag is
  122. only valid when starting a console application, otherwise it is ignored. If you
  123. are launching a GUI application, use the C<window_attr> tag instead.
  124. By default, the process shares its parent's console.
  125. =item stdin
  126. An open input filehandle, or the name of an existing file. The resulting
  127. filehandle will be used for the child's standard input handle.
  128. By default, the child process shares the parent's standard input.
  129. =item stdout
  130. An open output filehandle or filename (will be opened for append). The
  131. resulting filehandle will be used for the child's standard output handle.
  132. By default, the child process shares the parent's standard output.
  133. =item stderr
  134. An open output filehandle or filename (will be opened for append). The
  135. resulting filehandle will be used for the child's standard error handle.
  136. By default, the child process shares the parent's standard error.
  137. =back
  138. Unrecognized keys are ignored.
  139. =back
  140. =item 3
  141. run()
  142. run($timeout, $which);
  143. Provides a simple way to run the programs with a time limit. The
  144. $timeout is in seconds with millisecond accuracy. This call blocks for
  145. up to $timeout seconds, or until the processes finish.
  146. The $which parameter specifies whether to wait for I<all> processes to
  147. complete within the $timeout, or whether to wait for I<any> process to
  148. complete. You should set this to a boolean, where a true value means to
  149. wait for I<all> the processes to complete, and a false value to wait
  150. for I<any>. If you do not specify $which, it defaults to true (C<all>).
  151. Returns a boolean indicating whether the processes exited by themselves,
  152. or whether the time expired. A true return value means the processes
  153. exited normally; a false value means one or more processes was killed
  154. will $timeout.
  155. You can get extended information on process exit codes using the
  156. status() method.
  157. For example, this is how to build two perl modules at the same time,
  158. with a 5 minute timeout:
  159. use Win32::Job;
  160. $job = Win32::Job->new;
  161. $job->spawn("cmd", q{cmd /C "cd Mod1 && nmake"});
  162. $job->spawn("cmd", q{cmd /C "cd Mod2 && nmake"});
  163. $ok = $job->run(5 * 60);
  164. print "Mod1 and Mod2 built ok!\n" if $ok;
  165. =item 4
  166. watch()
  167. watch(\&handler, $interval, $which);
  168. handler($job);
  169. Provides more fine-grained control over how to stop the programs. You specify
  170. a callback and an interval in seconds, and Win32::Job will call the "watchdog"
  171. function at this interval, either until the processes finish or your watchdog
  172. tells Win32::Job to stop. You must return a value indicating whether to stop: a
  173. true value means to terminate the processes immediately.
  174. The $which parameter has the same meaning as run()'s.
  175. Returns a boolean with the same meaning as run()'s.
  176. The handler may do anything it wants. One useful application of the watch()
  177. method is to check the filesize of the output file, and terminate the Job if
  178. the file becomes larger than a certain limit:
  179. use Win32::Job;
  180. $job = Win32::Job->new;
  181. $job->spawn("cmd", q{cmd /C "cd Mod1 && nmake"}, {
  182. stdin => 'NUL', # the NUL device
  183. stdout => 'stdout.log',
  184. stderr => 'stdout.log',
  185. });
  186. $ok = $job->watch(sub {
  187. return 1 if -s "stdout.log" > 1_000_000;
  188. }, 1);
  189. print "Mod1 built ok!\n" if $ok;
  190. =item 5
  191. status()
  192. status()
  193. Returns a hash containing information about the processes in the job.
  194. Only returns valid information I<after> calling either run() or watch();
  195. returns an empty hash if you have not yet called them. May be called from a
  196. watch() callback, in which case the C<exitcode> field should be ignored.
  197. The keys of the hash are the process IDs; the values are a subhash
  198. containing the following keys:
  199. =over 4
  200. =item exitcode
  201. The exit code returned by the process. If the process was killed because
  202. of a timeout, the value is 293.
  203. =item time
  204. The time accumulated by the process. This is yet another subhash containing
  205. the subkeys (i) C<user>, the amount of time the process spent in user
  206. space; (ii) C<kernel>, the amount of time the process spent in kernel space;
  207. and (iii) C<elapsed>, the total time the process was running.
  208. =back
  209. =item 6
  210. kill()
  211. kill();
  212. Kills all processes and subprocesses in the Job. Has no return value.
  213. Sets the exit code to all processes killed to 293, which you can check
  214. for in the status() return value.
  215. =back
  216. =head1 SEE ALSO
  217. For more information about jobs, see Microsoft's online help at
  218. http://msdn.microsoft.com/
  219. For other modules which do similar things (but not as well), see:
  220. =over 4
  221. =item 1
  222. Win32::Process
  223. Low-level access to creating processes in Win32. See L<Win32::Process>.
  224. =item 2
  225. Win32::Console
  226. Low-level access to consoles in Win32. See L<Win32::Console>.
  227. =item 3
  228. Win32::ProcFarm
  229. Manage pools of threads to perform CPU-intensive tasks on Windows. See
  230. L<Win32::ProcFarm>.
  231. =back
  232. =head1 AUTHOR
  233. ActiveState (support@ActiveState.com)
  234. =head1 COPYRIGHT
  235. Copyright (c) 2002, ActiveState Corporation. All Rights Reserved.
  236. =cut