Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
5.5 KiB

  1. #-----------------------------------------------------------------
  2. package WaitProc;
  3. #
  4. # Copyright (c) Microsoft Corporation. All rights reserved.
  5. #
  6. #
  7. # Version: 1.00 08/16/2001 : TSanders Initial design
  8. # 1.01 09/16/2001 : SuemiaoR Add functions for dependent processes
  9. #-----------------------------------------------------------------
  10. $VERSION = '1.00';
  11. use strict;
  12. use lib $ENV{ "RazzleToolPath" };
  13. use lib $ENV{ "RazzleToolPath" }. "\\PostBuildScripts";
  14. use Logmsg;
  15. use Win32::Process;
  16. ###-----------------------------------------------------------------//
  17. sub wait_proc($@)
  18. {
  19. my ( $maxProc, @cmdLine ) = @_;
  20. my ( @hProcList, $i, $hProc, $iProc, $pExitCode, $k, $x );
  21. my ( @mCmds, %holdCmds, $slot, $bitSlot );
  22. my ( $extSlot, @extCmd );
  23. @hProcList = ();
  24. if( $maxProc < 1 ) { $maxProc = $ENV{NUMBER_OF_PROCESSORS} * 2; }
  25. $slot = 0;
  26. $extSlot = 0;
  27. $bitSlot = 0;
  28. for ($i=0; $i < @cmdLine; $i++)
  29. {
  30. $slot = ($i % $maxProc) if( $i < $maxProc && !$extSlot );
  31. @mCmds = split( /\&/, $cmdLine[$i] );
  32. $hProc = create_proc($mCmds[0]);
  33. if($hProc)
  34. {
  35. logmsg("Executing Slot $slot -[ $mCmds[0]]");
  36. }
  37. else
  38. {
  39. errmsg("Failed to open process for $mCmds[0]");
  40. }
  41. $hProcList[$slot] = $hProc;
  42. $holdCmds{$slot} = $mCmds[1] if( $mCmds[1] );
  43. $bitSlot |= ( 1 << $slot );
  44. next if( ($i+1) < $maxProc && ($i+1) < @cmdLine );
  45. #####Start Virus Scan
  46. if( @extCmd && $extSlot < $maxProc )
  47. {
  48. for( $k=$maxProc; $k<( $maxProc*2); $k++)
  49. {
  50. last if( !(( $bitSlot >> $k) &1) );
  51. }
  52. if( $k < ( $maxProc*2) )
  53. {
  54. $cmdLine[$i] = shift( @extCmd );
  55. $slot = $k;
  56. ++$extSlot;
  57. --$i;
  58. next;
  59. }
  60. }
  61. while(1)
  62. {
  63. for($iProc = 0; $iProc < ($maxProc*2); $iProc++)
  64. {
  65. next if( !( ($bitSlot >> $iProc ) & 1 ) );
  66. eval{
  67. last if $hProcList[$iProc]->Win32::Process::Wait(1000);
  68. };
  69. if ($@){errmsg("Wait() failed on $iProc") && last;}
  70. }
  71. next if( $iProc == ($maxProc*2) );
  72. $hProcList[$iProc]->Win32::Process::GetExitCode($pExitCode);
  73. logmsg("Completed slot $iProc - ExitCode: $pExitCode");
  74. return 0 if( $pExitCode );
  75. $bitSlot &= ( ~( 1 << $iProc ) );
  76. last if( !$bitSlot && !$holdCmds{$iProc} && !@extCmd );
  77. $slot = $iProc;
  78. #####Free slot from main command - copy
  79. if( $iProc < $maxProc )
  80. {
  81. if( $holdCmds{$iProc} )
  82. {
  83. if( ($i+1) < @cmdLine )
  84. {
  85. push( @extCmd, $holdCmds{$iProc} );
  86. $holdCmds{$iProc} = "";
  87. }
  88. else
  89. {
  90. $cmdLine[$i] = $holdCmds{$iProc};
  91. $holdCmds{$iProc} = "";
  92. --$i;
  93. }
  94. last;
  95. }
  96. last if( ($i+1) < @cmdLine );
  97. }
  98. #####Free slot from depending command - virus scan
  99. else
  100. {
  101. if( !@extCmd )
  102. {
  103. --$extSlot;
  104. next;
  105. }
  106. #####Prepare next Virus Command in queue
  107. $cmdLine[$i] = shift( @extCmd );
  108. --$i;
  109. last;
  110. }
  111. }
  112. }
  113. return 1;
  114. }
  115. ###-----------------------------------------------------------------//
  116. sub create_proc($){
  117. my($hProc);
  118. my($cmd) = @_;
  119. Win32::Process::Create($hProc, "$ENV{windir}\\system32\\cmd.exe", " /c ".$cmd, 0, CREATE_NO_WINDOW, ".")
  120. || logmsg(Win32::FormatMessage(Win32::GetLastError()));
  121. return $hProc;
  122. }
  123. #--------------------------------------------------------------//
  124. #Function Usage
  125. #--------------------------------------------------------------//
  126. sub Usage
  127. {
  128. print <<USAGE;
  129. Executes maximum given N processes concurrently in the order of given lists.
  130. Usage: $0 -p p0.cmd -p p1.cmd ... -p pk.cmd [-n N]
  131. -p Process to execute
  132. -n Number of processes to execute at once.
  133. Defaults to %NUMBER_OF_PROCESSORS% *2
  134. -? Displays usage
  135. Examples:
  136. $0 -p:"copy arg1 arg2" -p:"copy arg1 arg2" -p:"copy arg1 arg2"... -n:2
  137. $0 -p:"copy arg1 arg2& scan arg1" -p:"copy arg1 arg2& scan arg1" -p:"copy arg1 arg2& scan arg1"... -n:2
  138. USAGE
  139. exit(1);
  140. }
  141. ###-----Cmd entry point for script.-------------------------------//
  142. if (eval("\$0 =~ /" . __PACKAGE__ . "\\.pm\$/i"))
  143. {
  144. use ParseArgs;
  145. my($maxProc, @procs);
  146. parseargs( '?' => \&Usage,
  147. 'n:' => \$maxProc,
  148. 'p:' => \@procs );
  149. exit ( !wait_proc($maxProc, @procs) );
  150. }
  151. #-------------------------------------------------------------//
  152. =head1 NAME
  153. WaitProc - From a list of given processes, run N simulataneously.
  154. =head1 SYNOPSIS
  155. use WaitProc;
  156. wait_proc( $N, @P );
  157. where $N is the number of processes to run simultaneously and @P is the list of p0, p1,...,pk processes to run
  158. =head1 DESCRIPTION
  159. Take as input a number: $N and list of processes: @P consisting of processes p0, p1 ... pk to execute simultaneously,
  160. at most $N at one time.
  161. If N is < 1 or not defined, N will default to 2 * %Number_of_processors%.
  162. p0, ... ,pk in @P will be of the standard format: "Command1 arg1 arg2 ... argN", "Command2 arg1 arg2 ... argN", ... , "CommandK arg1 arg2 ... argN",
  163. You can create a dependency between multiple process by submitting a single process p as:
  164. "Command1 arg1 arg2 ... argN &Command2 arg1 arg2 ... argN & ... & CommandK arg1 arg2 ... argN"
  165. =head1 NOTES
  166. A process p in @P is executed from a cmd prompt using the following syntax:
  167. cmd.exe /c minimize.exe & p
  168. =head1 AUTHOR
  169. Ted Sanders <[email protected]>
  170. =head1 COPYRIGHT
  171. Copyright (c) Microsoft Corporation. All rights reserved.
  172. =cut
  173. 1;