use threads;
use strict;

my $MaxThreads = 10;
my $UsedThreads = 0;

sub xsltApplyXSLTTemplate {
  my $node = shift;                       # Add whatever params you need

  my @TransformResult;                    # Here we gonna put our results.
                                          # Must be shared between threads
                                          # for write

  my @Nodes = $node->childNodes();        # We are going to recurse on them,
                                          # whoever they are

  my $NodesToProcess = scalar(@Nodes);    # How many childs do we posess?

  push @TransformResult, 'smth at start'; # We can't delegate everything,
                                          # here is the job we are doing\
                                          # ourselves

  my $i = 1;                              # 1 because we have done something
  for my $Child (@Nodes){
    if ($UsedThreads++ < $MaxThreads - 1  # If we haven't reached threadslimit
          && $i < $NodesToProcess - 1){   # limit and there is more, than one
      $TransformResult[$i] = undef;       # node left, we make new thread
                                          # note $UsedThreads write-lock on
                                          # check

      threads->create(sub{$TransformResult[$i] =
                          xsltApplyXSLTTemplate($Child)});

    } else {                              # if we only have one node to proc,
      $UsedThreads--;                     # we are doing it here. Same if
                                          # threads limit reached

      $TransformResult[$i] = xsltApplyXSLTTemplate($Child);
    }
    $i++;
  }
  my $AllChildsAreDone = 0;               # Now we make sure all threads
  do {                                    # finished their jobs
    $AllChildsAreDone = 1;
    for (@TransformResult){
      $AllChildsAreDone = 0 if !defined($_);
    }
  } while (!$AllChildsAreDone);

  push @TransformResult, 'something at end';

  return @TransformResult;                # that's it - we are done.
}
