deprecated/buildtools/buildsystemtools/BuildServer.pm
author marvin shi <marvin.shi@nokia.com>
Wed, 17 Nov 2010 16:47:55 +0800
changeset 696 30aa553e9465
parent 655 3f65fd25dfd4
permissions -rw-r--r--
features: bsym for rofsbuild and log input support for rombuild
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
655
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     1
# Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     2
# All rights reserved.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     3
# This component and the accompanying materials are made available
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     4
# under the terms of "Eclipse Public License v1.0"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     5
# which accompanies this distribution, and is available
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     6
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     7
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     8
# Initial Contributors:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     9
# Nokia Corporation - initial contribution.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    10
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    11
# Contributors:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    12
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    13
# Description:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    14
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    15
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    16
package BuildServer;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    17
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    18
use strict;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    19
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    20
use FindBin;		# for FindBin::Bin
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    21
use lib "$FindBin::Bin/lib/freezethaw"; # For FreezeThaw
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    22
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    23
# Other necessary modules. For "use Scanlog;" see dynamic code below.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    24
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    25
use Msg;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    26
use ParseXML;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    27
use FreezeThaw qw(freeze thaw);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    28
use IO::File;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    29
use File::Basename;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    30
use File::Copy;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    31
use Compress::Zlib;			  # For decompression library routines
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    32
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    33
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    34
# Globals
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    35
my @gCommands;                # Holds the parsed "Execute" data from the XML file.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    36
my @gSetEnv;                  # Holds the parsed "SetEnv" data from the XML file.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    37
my $gIDCount = 0;             # The current Execute ID we're processing.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    38
my $gStage;                   # The current Stage we're in.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    39
my %gClientEnvNum;            # Holds the current index into @gSetEnv for each client.  Indexed by client name.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    40
my %gClientStatus;            # Holds the status of each client.  Indexed by client name.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    41
my %gClientHandles;           # Holds the socket of each client.  Indexed by client name
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    42
my $gLogFileH;                # The logfile.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    43
my $gLogStarted = 0;          # Boolean to say if the logfile has been started.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    44
my $gRealTimeError = "";      # "" = No error, otherwise a string significant to AutoBuild's log parsing
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    45
my $gScanlogAvailable = 0;    # Boolean to say if scanlog is available.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    46
my $gExit = 0;                # 0 = FALSE (Do not exit) # 1 = TRUE (Send Exit to all clients for next command)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    47
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    48
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    49
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    50
# Check if HiRes Timer is available
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    51
my ($gHiResTimer) = 0; #Flag - true (1) if HiRes Timer module available
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    52
if (eval "require Time::HiRes;") {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    53
  $gHiResTimer = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    54
} else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    55
  print "Cannot load HiResTimer Module\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    56
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    57
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    58
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    59
# Check if Scanlog.pm is available.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    60
# In the Perforce order of things, scanlog.pm is in directory ".\scanlog" relative to BuildServer.pl
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    61
# However, at build time, BuildServer.pl is in "\EPOC32\Tools\Build" while scanlog.pm is in "\EPOC32\Tools"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    62
# i.e. in the parent directory relative to BuildServer.pl
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    63
# If Scanlog cannot be found in either place, we continue, but the Scanlog functionality will be skipped.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    64
if (eval {require scanlog::Scanlog;})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    65
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    66
  $gScanlogAvailable = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    67
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    68
elsif (eval {use lib $FindBin::Bin.'/..'; require Scanlog;})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    69
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    70
  $gScanlogAvailable = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    71
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    72
else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    73
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    74
  print "Cannot load Scanlog Module\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    75
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    76
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    77
# GetServerVersion
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    78
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    79
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    80
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    81
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    82
# Server Version Number
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    83
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    84
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    85
# This function returns the server version number
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    86
sub GetServerVersion
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    87
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    88
  return "1.3";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    89
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    90
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    91
# rcvd_msg_from_client
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    92
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    93
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    94
# $iConn (Instance of the Msg Module)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    95
# $msg (the recieved message from the client)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    96
# $err (any error message from the Msg Module)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    97
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    98
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    99
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   100
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   101
# This function processes the incoming message from the BuildClient and acts upon them
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   102
sub rcvd_msg_from_client {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   103
    my ($iConn, $msg, $err) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   104
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   105
    # If the message is empty or a "Bad file descriptor" error happens then it
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   106
    # usually means the the BuildServer has closed the socket connection.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   107
    # The BuildClient will keep trying to connect to a BuildServer
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   108
    if (($msg eq "") || ($err eq "Bad file descriptor"))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   109
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   110
      print "A client has probably Disconnected\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   111
      croak "ERROR: Cannot recover from Error: $err\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   112
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   113
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   114
    # Thaw the message, this decodes the text string sent from the client back into perl variables
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   115
    my ($iCommand, $iClientName, $iID, $iStage, $iComp, $iCwd, $iCommandline, $args) = thaw ($msg);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   116
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   117
    # Handle a "Ready" command. A client wishes to connect.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   118
    if ( $iCommand eq "Ready")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   119
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   120
      # Check the Client Version.  $iID holds the client version in the "Ready" message.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   121
      if ($iID ne &GetServerVersion)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   122
      {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   123
        die "ERROR: Client version \"$iID\" does not match Server version \"".&GetServerVersion."\", cannot continue\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   124
      }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   125
      # Handle the initial "Ready" Command from the client
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   126
      # Check that the Client name is unique
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   127
      if (defined $gClientHandles{$iClientName})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   128
      {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   129
        # The Client name is not unique, a client by this name has already connected
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   130
        warn "WARNING: Multiple Clients using the same name\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   131
        warn "Adding random number to client name to try and make it unique\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   132
        warn "This will affect the preference order of the Clients\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   133
        # Generate a ramdom number to add to the client name.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   134
        my ($iRNum) = int(rand 10000000);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   135
        $iClientName .= $iRNum;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   136
        print "Changing ClientName to \"$iClientName\"\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   137
        # Send the new Client name to the client
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   138
        my $iMsg = freeze("ChangeClientName", $iClientName);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   139
        $iConn->transmit_immediately($iMsg);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   140
      }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   141
      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   142
      # Add the connection object to the store of connections
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   143
      $gClientHandles{$iClientName} = $iConn;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   144
      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   145
      # Write the header to the logfile on first connection only
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   146
      if ( $gLogStarted == 0)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   147
      {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   148
        # The start of the log file only needs to be printed once
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   149
        $gLogStarted = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   150
        &PrintStageStart;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   151
      }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   152
      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   153
      # Set Environment Variable counter to zero
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   154
      # This client has not been sent any environment variables yet
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   155
      $gClientEnvNum{$iClientName} = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   156
      # Set the $iCommand variable so that we begin sending Environment Variables
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   157
      $iCommand = "SetEnv Ready";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   158
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   159
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   160
    # Handle the "SetEnv Ready" command.  The client is ready for a command or env var.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   161
    if ( $iCommand eq "SetEnv Ready")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   162
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   163
      # If there are any environment variables to be set, send the next one to the client to set it
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   164
      if (defined $gSetEnv[$gClientEnvNum{$iClientName}])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   165
      {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   166
        &Send_SetEnv($iConn, $gClientEnvNum{$iClientName});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   167
        $gClientEnvNum{$iClientName}++;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   168
      } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   169
        # The client has gone through the connect process and has been sent all its environment variables
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   170
        # Add this client to the list of client ready to process commands
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   171
        AddReady($iClientName, $iConn);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   172
      }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   173
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   174
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   175
    # Handle the "Results" command.  The client has finished a step and given us the results.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   176
    if ( $iCommand eq "Results")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   177
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   178
        $args = Decompress($args); # Decompress the results.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   179
        
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   180
        # If Scanlog has been found, check returned text for real time error string.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   181
        # If a client reports a real time error, set global flag. We can't just die here and 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   182
        # now; instead we must wait for other "busy" clients to finish their current tasks.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   183
        if ($gScanlogAvailable)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   184
        {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   185
            if (Scanlog::CheckForRealTimeErrors($args))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   186
            {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   187
                # Command returned a RealTimeBuild error - abort this script,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   188
                # and propagate it up to our parent process
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   189
                $gRealTimeError = "RealTimeBuild:";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   190
            }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   191
            elsif ($gCommands[$iID]{'ExitOnScanlogError'} =~ /y/i && Scanlog::CheckForErrors($args) )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   192
            {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   193
                # This is a critical step - flag a real time error,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   194
                # and don't process anything else in this script
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   195
                $gRealTimeError = "Realtime error (ExitOnScanlogError)";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   196
            }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   197
        }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   198
        
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   199
        # Print the correct headers for an individual command to the log
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   200
        print $gLogFileH "=== Stage=$gStage == $iComp\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   201
        print $gLogFileH "-- $iCommandline\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   202
        print $gLogFileH "--- $iClientName Executed ID ".($iID+1)."\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   203
        # Print the output of the command into the log
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   204
        print $gLogFileH "$args";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   205
        # Flush the handle to try and make sure the logfile is up to date
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   206
        $gLogFileH->flush;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   207
        # Add this client to the list of client ready to process commands
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   208
        AddReady($iClientName, $iConn);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   209
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   210
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   211
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   212
# Send_SetEnv
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   213
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   214
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   215
# $iOrder - index into @gSetEnv
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   216
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   217
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   218
# Sends frozen SetEnv message
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   219
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   220
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   221
# This function is used to produce frozen SetEnv messages from the hash and then sends its
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   222
sub Send_SetEnv
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   223
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   224
  my ($iConn, $iOrder) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   225
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   226
  my $iName = $gSetEnv[$iOrder]{'Name'};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   227
  my $iValue = $gSetEnv[$iOrder]{'Value'};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   228
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   229
  my $iMsg = freeze ('SetEnv', $iName, $iValue);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   230
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   231
  $iConn->transmit_immediately($iMsg);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   232
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   233
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   234
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   235
# login_proc
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   236
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   237
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   238
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   239
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   240
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   241
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   242
# This function can be used to process a login procedure
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   243
# No login procedure is implemented
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   244
sub login_proc {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   245
    # Unconditionally accept
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   246
    \&rcvd_msg_from_client;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   247
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   248
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   249
# Start
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   250
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   251
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   252
# $iDataSource (XML Command file)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   253
# $iPort (Port number to listen on for Build Clients)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   254
# $iLogFile (Logfile to write output from Build Clients to)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   255
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   256
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   257
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   258
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   259
# This function starts the server
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   260
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   261
sub Start
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   262
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   263
  my ($iDataSource, $iPort, $iLogFile, $iEnvSource, $iConnectionTimeout, $iSocketConnections) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   264
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   265
  my ($iHost) = '';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   266
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   267
  # Open the log file for writing, it will not overwrite logs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   268
  $gLogFileH = IO::File->new("> $iLogFile")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   269
    or croak "ERROR: Couldn't open \"$iLogFile\" for writing: $!\n";  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   270
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   271
  # If $iEnvSource is defined the Environment needs to be processed from this file
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   272
  if (defined $iEnvSource)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   273
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   274
    # Parse the XML data
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   275
    my ($iCommands, $iSetEnv) = &ParseXML::ParseXMLData($iEnvSource);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   276
    push @gSetEnv, @$iSetEnv;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   277
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   278
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   279
  # Parse the XML data
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   280
  my ($iCommands, $iSetEnv) = &ParseXML::ParseXMLData($iDataSource);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   281
  push @gCommands, @$iCommands;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   282
  push @gSetEnv, @$iSetEnv;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   283
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   284
  # Assuming there are commands to be executed, initialise the "current stage"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   285
  # variable with the stage of the first command
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   286
  $gStage = $gCommands[$gIDCount]{'Stage'} if (scalar @gCommands);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   287
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   288
  # Create the TCP/IP listen socket
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   289
  Msg->recent_agent($iPort, $iHost, \&login_proc, $iConnectionTimeout, $iSocketConnections);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   290
  print "BuildServer created. Waiting for BuildClients\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   291
  # Enter event loop to process incoming connections and messages
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   292
  Msg->result_iteration();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   293
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   294
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   295
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   296
# SendCommand
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   297
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   298
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   299
# $iConn - the socket to use
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   300
# $iID - the ID of the command
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   301
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   302
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   303
# Command or file or file request sent via TCP connection
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   304
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   305
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   306
# Sends the command or file or file request indexed by $iID to the client
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   307
sub SendCommand
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   308
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   309
  my ($iConn, $iID) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   310
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   311
  my $msg;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   312
  my $iData;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   313
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   314
  $msg = freeze ($gCommands[$iID]{'Type'}, $iID, $gCommands[$iID]{'Stage'}, $gCommands[$iID]{'Component'}, $gCommands[$iID]{'Cwd'}, $gCommands[$iID]{'CommandLine'});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   315
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   316
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   317
  $iConn->transmit_immediately($msg);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   318
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   319
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   320
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   321
# AddReady
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   322
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   323
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   324
# $iClientName (Client name)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   325
# $iConn (Connection Object)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   326
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   327
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   328
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   329
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   330
# This function adds the client defined by the connection ($iConn) to the list of ready clients
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   331
# It also sends new commands to clients if apropriate
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   332
sub AddReady
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   333
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   334
  my ($iClientName, $iConn) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   335
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   336
  my @iClientsWaiting;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   337
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   338
  # Set the client status to the "Waiting" State
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   339
  $gClientStatus{$iClientName} = "Waiting";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   340
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   341
  # If the next command is Exit set global Exit flag
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   342
  if (defined $gCommands[$gIDCount])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   343
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   344
    $gExit = 1 if ($gCommands[$gIDCount]{'Type'} eq "Exit");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   345
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   346
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   347
  # Add the all "Waiting" clients to a list of waiting Clients
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   348
  foreach my $iClient (keys %gClientStatus)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   349
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   350
    push @iClientsWaiting, $iClient if ($gClientStatus{$iClient} eq "Waiting");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   351
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   352
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   353
  # Are all the clients waiting?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   354
  if (scalar @iClientsWaiting == $iConn->AllAssociations)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   355
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   356
    # Everyone has finished.  Everyone is waiting.  One of 3 things has happened:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   357
    # - There has been a realtime error.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   358
    # - All commands have been run.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   359
    # - We have come to the end of the current stage.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   360
    # - There is only one client, and it has further commands in the current stage.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   361
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   362
    if ($gRealTimeError)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   363
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   364
      &PrintStageEnd;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   365
      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   366
      print $gLogFileH "ERROR: $gRealTimeError BuildServer terminating\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   367
      close ($gLogFileH);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   368
      die "ERROR: $gRealTimeError BuildServer terminating\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   369
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   370
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   371
    # If all other clients waiting for a command and an exit pending
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   372
    # Send Messages to all clients (not just current) to exit their procees
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   373
    # No return is expected so exit the buildserver process
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   374
    if ($gExit)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   375
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   376
      # Close up log nicely
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   377
      &PrintStageEnd;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   378
      foreach my $key (keys %gClientHandles)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   379
      {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   380
        my $msg = freeze ("Exit");  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   381
        $gClientHandles{$key}->transmit_immediately($msg);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   382
      }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   383
      exit 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   384
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   385
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   386
    if (!defined $gCommands[$gIDCount])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   387
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   388
      # All commands have been run.  There are no more commands.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   389
      &PrintStageEnd;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   390
      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   391
      print "No more stages\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   392
      close ($gLogFileH);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   393
      # Exit successfully
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   394
      exit 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   395
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   396
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   397
    if ( !defined $gStage ||                # the last command had no stage set
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   398
         $gStage eq '' ||                   # the last command had no stage set
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   399
         $gStage != $gCommands[$gIDCount]{'Stage'}   # the last command's stage is different to the next command's stage
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   400
       )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   401
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   402
      # We've successfully reached the end of a stage
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   403
      &PrintStageEnd;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   404
      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   405
      # Update the current stage variable to be the stage of the next command
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   406
      $gStage = $gCommands[$gIDCount]{'Stage'};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   407
      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   408
      &PrintStageStart;    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   409
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   410
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   411
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   412
  # If the next command is the first in a stage then all clients are waiting.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   413
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   414
  # Below this point we are approaching the command sending section.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   415
  # Other clients could be working on previous commands at this point.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   416
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   417
  # If the next command can not be run in parallel with the previous command
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   418
  # and another client is executing the previous command, then we should
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   419
  # return and simply wait for the other client to finish.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   420
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   421
  # Don't issue anymore commands if there is an exit pending
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   422
  return if ($gExit);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   423
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   424
  # Don't issue anymore commands if there has been a realtime error.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   425
  return if ($gRealTimeError);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   426
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   427
  # Sort the waiting clients alphabetically
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   428
  @iClientsWaiting = sort(@iClientsWaiting);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   429
  # Extract the first client name
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   430
  my $iClient = shift @iClientsWaiting;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   431
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   432
  # Check if there are commands and clients available
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   433
  while (defined $gCommands[$gIDCount] and defined $iClient)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   434
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   435
    # Check if the next command's stage is different to the current stage.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   436
    # They will be identical if we are running the first command in a stage.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   437
    # They will also be identical if we are running a subsequent command in the same stage.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   438
    # So if they are different it means the next command is in a different stage.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   439
    # Therefore we want to return and wait until all other clients have finished before
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   440
    # sending this command.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   441
    return if ($gStage ne $gCommands[$gIDCount]{'Stage'});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   442
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   443
    # Check to make sure a Exit command is not sent to 1 of multiple clients if Exit was not in it's own stage
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   444
    return if ($gCommands[$gIDCount]{'Type'} eq "Exit");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   445
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   446
    # If at least one client is doing some work, and both the previous and next
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   447
    # commands' stages are not set, just wait until the working client finishes.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   448
    # So we treat two steps with no stage name as though a stage change has occurred between them.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   449
    if ((!defined $gCommands[$gIDCount-1]{'Stage'} or '' eq $gCommands[$gIDCount-1]{'Stage'}) and
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   450
        (!defined $gCommands[$gIDCount]{'Stage'} or '' eq $gCommands[$gIDCount]{'Stage'}) )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   451
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   452
      foreach my $status (values %gClientStatus)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   453
      {      
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   454
        return if ($status ne 'Waiting');
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   455
      }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   456
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   457
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   458
    print "Sending Step ". ($gIDCount+1) ." to $iClient\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   459
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   460
    # Set client as "Busy" and then send the command
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   461
    $gClientStatus{$iClient} = "Busy";    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   462
    &SendCommand($gClientHandles{$iClient}, $gIDCount);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   463
    $gIDCount++;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   464
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   465
    # Extract the next client name
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   466
    $iClient = shift @iClientsWaiting;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   467
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   468
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   469
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   470
sub PrintStageStart
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   471
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   472
  # Output to log that the Stage has started
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   473
  print $gLogFileH "===-------------------------------------------------\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   474
  print $gLogFileH "=== Stage=$gStage\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   475
  print $gLogFileH "===-------------------------------------------------\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   476
  print $gLogFileH "=== Stage=$gStage started ".localtime()."\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   477
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   478
  # Flush the handle to try and make sure the logfile is up to date
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   479
  $gLogFileH->flush;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   480
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   481
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   482
sub PrintStageEnd
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   483
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   484
  print "Stage End $gStage\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   485
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   486
  # Output to the log that the Stage has finished
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   487
  print $gLogFileH "=== Stage=$gStage finished ".localtime()."\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   488
  # Flush the handle to try and make sure the logfile is up to date
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   489
  $gLogFileH->flush;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   490
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   491
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   492
# TimeStampStart
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   493
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   494
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   495
# $iData - Reference to variable to put the start time stamp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   496
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   497
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   498
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   499
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   500
# This places a timestamp in the logs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   501
sub TimeStampStart
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   502
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   503
  my $ref = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   504
  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   505
  # Add the client side per command start timestamp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   506
  $$ref = "++ Started at ".localtime()."\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   507
  # Add the client side per command start HiRes timestamp if available
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   508
  if ($gHiResTimer == 1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   509
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   510
    $$ref .= "+++ HiRes Start ".Time::HiRes::time()."\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   511
  } else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   512
    # Add the HiRes timer unavailable statement
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   513
    $$ref .= "+++ HiRes Time Unavailable\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   514
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   515
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   516
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   517
# TimeStampEnd
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   518
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   519
# Inputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   520
# $iData - Reference to variable to put the end time stamp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   521
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   522
# Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   523
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   524
# Description
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   525
# This places a timestamp in the logs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   526
sub TimeStampEnd
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   527
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   528
  my $ref = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   529
 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   530
  # Add the client side per command end HiRes timestamp if available
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   531
  $$ref .= "+++ HiRes End ".Time::HiRes::time()."\n" if ($gHiResTimer == 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   532
   # Add the client side per command end timestamp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   533
  $$ref .= "++ Finished at ".localtime()."\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   534
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   535
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   536
# Subroutine for decompressing data stream.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   537
# Input: message to be decompressed.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   538
# Output: decompressed message.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   539
# Note: here, when decompression is taking place, usually a complete message
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   540
# is passed as the input parameter; in this case Z_STREAM_END is the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   541
# returned status. If an empty message is decompressed (e.g. because ""
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   542
# was sent) Z_OK is returned.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   543
sub Decompress($)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   544
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   545
    my $msg = shift; # Get the message.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   546
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   547
    # Initialise deflation stream
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   548
    my ($x, $init_status);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   549
    eval { ($x, $init_status) = inflateInit() or die "Cannot create an inflation stream\n"; };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   550
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   551
    if($@) # Inflation initialisation has failed.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   552
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   553
	    return "ERROR: Decompression initialisation failed: $@\nERROR: zlib error message: ", $x->msg(), "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   554
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   555
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   556
    # Some other failure?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   557
    if($init_status != Z_OK and !defined($x))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   558
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   559
        return "ERROR: Decompression initialisation failed: $init_status\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   560
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   561
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   562
    # Decompress the message
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   563
    my ($output, $status);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   564
    eval { ($output, $status) = $x->inflate(\$msg) or die "ERROR: Unable to decompress message"; };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   565
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   566
    if($@) # Failure of decompression
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   567
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   568
	    return "ERROR: unable to decompress: $@\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   569
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   570
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   571
    # Some other failure?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   572
    if($status != Z_STREAM_END and $status != Z_OK)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   573
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   574
        my $error = $x->msg();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   575
        return "ERROR: Decompression failed: $error\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   576
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   577
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   578
    # Return the decompressed output.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   579
    return $output;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   580
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   581
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   582
1;