Init libparallel-forkmanager-perl accepted/tizen_devbase_tools devel devel-py2 master release-20170915 accepted/tizen/devbase/tools/20190927.044820 accepted/tizen/devbase/tools/20200104.060204 accepted/tizen/devbase/tools/20200106.014318 accepted/tizen/devbase/tools/20200109.052806 accepted/tizen/devbase/tools/20200110.011836 accepted/tizen/devbase/tools/20200114.020214 accepted/tizen/devbase/tools/20200114.115819 accepted/tizen/devbase/tools/20200115.231451 accepted/tizen/devbase/tools/20200219.094545 accepted/tizen/devbase/tools/20200415.093459 accepted/tizen/devbase/tools/20200423.100552 accepted/tizen/devbase/tools/20200514.023610 accepted/tizen/devbase/tools/20200520.012811 accepted/tizen/devbase/tools/20200618.010546 accepted/tizen/devbase/tools/20200623.003404 accepted/tizen/devbase/tools/20201105.013051 accepted/tools/devbase/tools/legacy/20240422.110749 accepted/tools/devbase/tools/legacy/20240423.040639 accepted/tools/devbase/tools/legacy/20240424.050621 submit/devel/20190730.074610 submit/trunk/20190927.012842 submit/trunk/20191017.111201 submit/trunk/20191017.233826 submit/trunk/20191030.112603 submit/trunk/20191101.102136 submit/trunk/20200104.111033 submit/trunk/20200104.134833 submit/trunk/20200105.091954 submit/trunk/20200108.172702 submit/trunk/20200109.105802 submit/trunk/20200109.112402 submit/trunk/20200109.124502 submit/trunk/20200109.151502 submit/trunk/20200109.154402 submit/trunk/20200110.111659 submit/trunk/20200114.100000 submit/trunk/20200114.110000 submit/trunk/20200115.110101 submit/trunk/20200219.120523 submit/trunk/20200409.194520 submit/trunk/20200409.200220 submit/trunk/20200409.202020 submit/trunk/20200410.143020 submit/trunk/20200410.160020 submit/trunk/20200413.132320 submit/trunk/20200413.150000 submit/trunk/20200413.150500 submit/trunk/20200413.151000 submit/trunk/20200414.141500 submit/trunk/20200414.173500 submit/trunk/20200414.191000 submit/trunk/20200422.115210 submit/trunk/20200422.142510 submit/trunk/20200422.165210 submit/trunk/20200423.102810 submit/trunk/20200423.115423 submit/trunk/20200423.122334 submit/trunk/20200513.162810 submit/trunk/20200519.161030 submit/trunk/20200519.164610 submit/trunk/20200519.184310 submit/trunk/20200612.131210 submit/trunk/20200612.180310 submit/trunk/20200612.182210 submit/trunk/20200612.185510 submit/trunk/20200612.191020 submit/trunk/20200615.140020 submit/trunk/20200617.133020 submit/trunk/20200619.141212 submit/trunk/20200622.151812 submit/trunk/20201029.114030 submit/trunk/20201029.132130 submit/trunk/20201029.140230 submit/trunk/20201030.104730 submit/trunk/20201030.143530 submit/trunk/20201102.094730 submit/trunk/20201104.132730
authorscm <Shuai>
Mon, 11 Sep 2017 06:51:55 +0000 (14:51 +0800)
committerscm <Shuai>
Mon, 11 Sep 2017 06:53:03 +0000 (14:53 +0800)
Change-Id: I93f1c84ed036116c3538adc825b4624f8745d826
Signed-off-by: scm <Shuai>
45 files changed:
Parallel-ForkManager-1.17/CONTRIBUTORS [new file with mode: 0644]
Parallel-ForkManager-1.17/Changes [new file with mode: 0644]
Parallel-ForkManager-1.17/INSTALL [new file with mode: 0644]
Parallel-ForkManager-1.17/MANIFEST [new file with mode: 0644]
Parallel-ForkManager-1.17/META.json [new file with mode: 0644]
Parallel-ForkManager-1.17/META.yml [new file with mode: 0644]
Parallel-ForkManager-1.17/MYMETA.json [new file with mode: 0644]
Parallel-ForkManager-1.17/MYMETA.yml [new file with mode: 0644]
Parallel-ForkManager-1.17/Makefile [new file with mode: 0644]
Parallel-ForkManager-1.17/Makefile.PL [new file with mode: 0644]
Parallel-ForkManager-1.17/README.mkdn [new file with mode: 0644]
Parallel-ForkManager-1.17/SIGNATURE [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/arch/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/arch/auto/Parallel/ForkManager/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/bin/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/lib/Parallel/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/lib/Parallel/ForkManager.pm [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/lib/auto/Parallel/ForkManager/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/man1/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/man3/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/man3/Parallel::ForkManager.3pm [new file with mode: 0644]
Parallel-ForkManager-1.17/blib/script/.exists [new file with mode: 0644]
Parallel-ForkManager-1.17/cpanfile [new file with mode: 0644]
Parallel-ForkManager-1.17/doap.xml [new file with mode: 0644]
Parallel-ForkManager-1.17/examples/callback.pl [new file with mode: 0755]
Parallel-ForkManager-1.17/examples/callback_data.pl [new file with mode: 0644]
Parallel-ForkManager-1.17/examples/parallel_get.pl [new file with mode: 0755]
Parallel-ForkManager-1.17/lib/Parallel/ForkManager.pm [new file with mode: 0644]
Parallel-ForkManager-1.17/pm_to_blib [new file with mode: 0644]
Parallel-ForkManager-1.17/t/00-compile.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/00-load.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/00-report-prereqs.dd [new file with mode: 0644]
Parallel-ForkManager-1.17/t/00-report-prereqs.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/01-utf8-all.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/02-callback.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/03-callback-data.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/basic-methods.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/callback.txt [new file with mode: 0644]
Parallel-ForkManager-1.17/t/callback_data.txt [new file with mode: 0644]
Parallel-ForkManager-1.17/t/waitpid-conflict.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/waitpid-waitonechild.t [new file with mode: 0644]
Parallel-ForkManager-1.17/t/waitpid_blocking.t [new file with mode: 0644]
Parallel-ForkManager-1.17/xt/release/pause-permissions.t [new file with mode: 0644]
Parallel-ForkManager-1.17/xt/release/unused-vars.t [new file with mode: 0644]
packaging/libparallel-forkmanager-perl.spec [new file with mode: 0644]

diff --git a/Parallel-ForkManager-1.17/CONTRIBUTORS b/Parallel-ForkManager-1.17/CONTRIBUTORS
new file mode 100644 (file)
index 0000000..07338b5
--- /dev/null
@@ -0,0 +1,12 @@
+
+# PARALLEL-FORKMANAGER CONTRIBUTORS #
+
+This is the (likely incomplete) list of people who have helped
+make this distribution what it is, either via code contributions, 
+patches, bug reports, help with troubleshooting, etc. A huge
+'thank you' to all of them.
+
+    * Ninebit
+    * Shlomi Fish
+
+
diff --git a/Parallel-ForkManager-1.17/Changes b/Parallel-ForkManager-1.17/Changes
new file mode 100644 (file)
index 0000000..b6b220d
--- /dev/null
@@ -0,0 +1,131 @@
+Revision history for Perl extension Parallel::ForkManager.
+
+1.17 2015-11-28
+  - Up Test::More's dependency version to v0.94 (because of 'subtest'). 
+    (GH#8, mauke)
+
+  [ STATISTICS ]
+    - code churn: 3 files changed, 88 insertions(+), 70 deletions(-)
+
+1.16 2015-10-08
+  - wait_one_child wasn't waiting at all. (RT#107634, Slaven Rezic, Yanick)
+
+  [ STATISTICS ]
+    - code churn: 10 files changed, 517 insertions(+), 461 deletions(-)
+
+1.15 2015-07-08
+  - test's watchdog actually exit if it's being hit. (RT#105747, Zefram)
+  - condition to catch children reaped by external forces improved.
+    (RT#105748, Zefram + Yanick)
+
+1.14 2015-05-17
+  - Add 'reap_finished_children', 'is_child' and 'is_parent'. (GH#6, Nine
+    bit)
+
+1.13 2015-05-11
+  - Use 'select' instead of sleep in _waitpid_blocking. (GH#5)
+
+1.12 2015-02-23
+  - Allow to use true blocking calls. (RT#102305)
+
+1.11 2015-01-30
+  - Promote to non-dev release.
+
+1.10_2 2015-01-25
+  - Put the problematic test as a TODO.
+
+1.10_1 2015-01-22
+  - Increase timeouts in test to address FreeBSD failures.
+
+1.09 2015-01-08
+  - Test was failing on Windows platforms. (Yanick Champoux)
+
+1.08 2015-01-07
+  - New helper functions 'max_procs', 'running_procs' and
+    'wait_for_available_procs'. GH#4 (Yanick Champoux)
+  - Play nicer with calls to 'waitpid' done outside of P::FM. GH#3 (Yanick
+    Champoux)
+
+1.07 2014-11-10
+  - Increase minimal Test::Simple requirement RT #92801
+  - Implement better style and practices in the examples in the POD.
+    (Shlomi Fish)
+
+1.06 2013-12-24
+  - Remove temporary directory only if it was an automatically generated
+    one. Now fixed. (Shoichi Kaji) RT #89590 (johantheolive)
+
+1.05 2013-09-18
+  - Remove temporary directory only if it was an automatically generated
+    one. (reported by Manuel Jeckelmann)
+
+1.04 2013-09-03
+  - Require File::Path 2.0 to support Perl 5.8 (Ian Burrell)
+  - fix some typos #88358 (David Steinbrunner)
+  - documentation fixes #84337 (Damyan Ivanov)
+
+1.03 2013-03-06
+  - Use second parameter from new() that was unused in the last few
+    released. (Michael Gang)
+
+1.02 2012-12-24
+  - Fix test for Windows.
+
+1.01 2012-12-23
+  - Disable utf8 test on Windows where it is a perl bug.
+  - Change version number scheme to two parts.
+
+1.0.0 2012-12-23
+  - Fixing RT 68298 - Insecure /tmp file handling using File::Temp::tempdir
+    by John Lightsey (LIGHTSEY)
+  - Adding another callback example and several tests Gabor Szabo (SZABGAB)
+
+0.7 2001-04-04
+  - callback code tested, exit status return (Chuck, dLux)
+  - added parallel_get.pl, a parallel webget example (dLux)
+  - added callbacks.pl, a callback example (Chuck, dLux)
+  - documentation updtes (Chuck, dLux)
+
+0.6 2000-11-30
+  - documentation tweak fixes by Noah Robin
+  - warning elimination fixes
+
+0.5 2000-10-18
+  - original version; created by h2xs 1.19
+
+0.7.9 2010-11-01
+  - Exclude the example scripts from getting installed.
+    (https://rt.cpan.org/Public/Bug/Display.html?id=62506)
+
+0.7.8 2010-08-25
+  - Make $VERSION compatible with the most perl versions possible
+    (http://rt.cpan.org/Public/Bug/Display.html?id=62180)
+
+0.7.7 2010-09-28
+  - Small distribution fixes
+
+0.7.6 2010-08-15
+  - Added datastructure retrieval (Ken Clarke)
+  - Using CORE::exit instead of exit
+    (http://rt.cpan.org/Public/Bug/Display.html?id=39003)
+
+0.7.5 2002-12-25
+  - Documentation fixes
+  - Fix bug if you specify max_procs = 0
+
+0.7.4 2002-07-04
+  - on_wait callback now runs from the wait_all_children method
+  - run_on_wait can run a task periodically, not only once.
+
+0.7.3 2001-08-24
+  - minor bugfix on calling the "on_finish" callback
+
+0.7.2 2001-05-14
+  - win32 port
+  - fix for the broken wait_one_child
+
+0.7.1 2001-04-26
+  - various semantical and grammar fixes in the documentation
+  - on_finish now get the exit signal also
+  - on_start now get the process-identification also
+  - described limitations in the doc
diff --git a/Parallel-ForkManager-1.17/INSTALL b/Parallel-ForkManager-1.17/INSTALL
new file mode 100644 (file)
index 0000000..af77424
--- /dev/null
@@ -0,0 +1,43 @@
+This is the Perl distribution Parallel-ForkManager.
+
+Installing Parallel-ForkManager is straightforward.
+
+## Installation with cpanm
+
+If you have cpanm, you only need one line:
+
+    % cpanm Parallel::ForkManager
+
+If you are installing into a system-wide directory, you may need to pass the
+"-S" flag to cpanm, which uses sudo to install the module:
+
+    % cpanm -S Parallel::ForkManager
+
+## Installing with the CPAN shell
+
+Alternatively, if your CPAN shell is set up, you should just be able to do:
+
+    % cpan Parallel::ForkManager
+
+## Manual installation
+
+As a last resort, you can manually install it. Download the tarball, untar it,
+then build it:
+
+    % perl Makefile.PL
+    % make && make test
+
+Then install it:
+
+    % make install
+
+If you are installing into a system-wide directory, you may need to run:
+
+    % sudo make install
+
+## Documentation
+
+Parallel-ForkManager documentation is available as POD.
+You can run perldoc from a shell to read the documentation:
+
+    % perldoc Parallel::ForkManager
diff --git a/Parallel-ForkManager-1.17/MANIFEST b/Parallel-ForkManager-1.17/MANIFEST
new file mode 100644 (file)
index 0000000..ca8628a
--- /dev/null
@@ -0,0 +1,30 @@
+CONTRIBUTORS
+Changes
+INSTALL
+MANIFEST
+META.json
+META.yml
+Makefile.PL
+README.mkdn
+SIGNATURE
+cpanfile
+doap.xml
+examples/callback.pl
+examples/callback_data.pl
+examples/parallel_get.pl
+lib/Parallel/ForkManager.pm
+t/00-compile.t
+t/00-load.t
+t/00-report-prereqs.dd
+t/00-report-prereqs.t
+t/01-utf8-all.t
+t/02-callback.t
+t/03-callback-data.t
+t/basic-methods.t
+t/callback.txt
+t/callback_data.txt
+t/waitpid-conflict.t
+t/waitpid-waitonechild.t
+t/waitpid_blocking.t
+xt/release/pause-permissions.t
+xt/release/unused-vars.t
diff --git a/Parallel-ForkManager-1.17/META.json b/Parallel-ForkManager-1.17/META.json
new file mode 100644 (file)
index 0000000..63f17ab
--- /dev/null
@@ -0,0 +1,84 @@
+{
+   "abstract" : "A simple parallel processing fork manager",
+   "author" : [
+      "dLux (Szabó, Balázs) <dlux@dlux.hu>",
+      "Yanick Champoux <yanick@cpan.org>",
+      "Gabor Szabo <gabor@szabgab.com>"
+   ],
+   "dynamic_config" : 0,
+   "generated_by" : "Dist::Zilla version 5.040, CPAN::Meta::Converter version 2.150001",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+      "version" : "2"
+   },
+   "name" : "Parallel-ForkManager",
+   "prereqs" : {
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0"
+         }
+      },
+      "develop" : {
+         "requires" : {
+            "Test::More" : "0.96",
+            "Test::PAUSE::Permissions" : "0",
+            "Test::Vars" : "0",
+            "warnings" : "0"
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "Carp" : "0",
+            "File::Path" : "0",
+            "File::Spec" : "0",
+            "File::Temp" : "0",
+            "POSIX" : "0",
+            "Storable" : "0",
+            "strict" : "0"
+         }
+      },
+      "test" : {
+         "recommends" : {
+            "CPAN::Meta" : "2.120900"
+         },
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0",
+            "File::Spec" : "0",
+            "IO::Handle" : "0",
+            "IPC::Open3" : "0",
+            "Test::More" : "0.94",
+            "Test::Warn" : "0",
+            "perl" : "5.006",
+            "warnings" : "0"
+         }
+      }
+   },
+   "provides" : {
+      "Parallel::ForkManager" : {
+         "file" : "lib/Parallel/ForkManager.pm",
+         "version" : "1.17"
+      }
+   },
+   "release_status" : "stable",
+   "resources" : {
+      "bugtracker" : {
+         "web" : "https://github.com/dluxhu/perl-parallel-forkmanager/issues"
+      },
+      "homepage" : "https://github.com/dluxhu/perl-parallel-forkmanager",
+      "repository" : {
+         "type" : "git",
+         "url" : "https://github.com/dluxhu/perl-parallel-forkmanager.git",
+         "web" : "https://github.com/dluxhu/perl-parallel-forkmanager"
+      }
+   },
+   "version" : "1.17",
+   "x_authority" : "cpan:DLUX",
+   "x_contributors" : [
+      "Ninebit <kevin@9b.io>",
+      "Shlomi Fish <shlomif@shlomifish.org>"
+   ]
+}
+
diff --git a/Parallel-ForkManager-1.17/META.yml b/Parallel-ForkManager-1.17/META.yml
new file mode 100644 (file)
index 0000000..ef5cb2e
--- /dev/null
@@ -0,0 +1,45 @@
+---
+abstract: 'A simple parallel processing fork manager'
+author:
+  - 'dLux (Szabó, Balázs) <dlux@dlux.hu>'
+  - 'Yanick Champoux <yanick@cpan.org>'
+  - 'Gabor Szabo <gabor@szabgab.com>'
+build_requires:
+  ExtUtils::MakeMaker: '0'
+  File::Spec: '0'
+  IO::Handle: '0'
+  IPC::Open3: '0'
+  Test::More: '0.94'
+  Test::Warn: '0'
+  perl: '5.006'
+  warnings: '0'
+configure_requires:
+  ExtUtils::MakeMaker: '0'
+dynamic_config: 0
+generated_by: 'Dist::Zilla version 5.040, CPAN::Meta::Converter version 2.150001'
+license: perl
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: '1.4'
+name: Parallel-ForkManager
+provides:
+  Parallel::ForkManager:
+    file: lib/Parallel/ForkManager.pm
+    version: '1.17'
+requires:
+  Carp: '0'
+  File::Path: '0'
+  File::Spec: '0'
+  File::Temp: '0'
+  POSIX: '0'
+  Storable: '0'
+  strict: '0'
+resources:
+  bugtracker: https://github.com/dluxhu/perl-parallel-forkmanager/issues
+  homepage: https://github.com/dluxhu/perl-parallel-forkmanager
+  repository: https://github.com/dluxhu/perl-parallel-forkmanager.git
+version: '1.17'
+x_authority: cpan:DLUX
+x_contributors:
+  - 'Ninebit <kevin@9b.io>'
+  - 'Shlomi Fish <shlomif@shlomifish.org>'
diff --git a/Parallel-ForkManager-1.17/MYMETA.json b/Parallel-ForkManager-1.17/MYMETA.json
new file mode 100644 (file)
index 0000000..f0421ad
--- /dev/null
@@ -0,0 +1,88 @@
+{
+   "abstract" : "A simple parallel processing fork manager",
+   "author" : [
+      "dLux (Szabó, Balázs) <dlux@dlux.hu>",
+      "Yanick Champoux <yanick@cpan.org>",
+      "Gabor Szabo <gabor@szabgab.com>"
+   ],
+   "dynamic_config" : 0,
+   "generated_by" : "Dist::Zilla version 5.040, CPAN::Meta::Converter version 2.150001, CPAN::Meta::Converter version 2.120921",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+      "version" : "2"
+   },
+   "name" : "Parallel-ForkManager",
+   "prereqs" : {
+      "build" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0"
+         }
+      },
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0"
+         }
+      },
+      "develop" : {
+         "requires" : {
+            "Test::More" : "0.96",
+            "Test::PAUSE::Permissions" : "0",
+            "Test::Vars" : "0",
+            "warnings" : "0"
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "Carp" : "0",
+            "File::Path" : "0",
+            "File::Spec" : "0",
+            "File::Temp" : "0",
+            "POSIX" : "0",
+            "Storable" : "0",
+            "perl" : "5.006",
+            "strict" : "0"
+         }
+      },
+      "test" : {
+         "recommends" : {
+            "CPAN::Meta" : "2.120900"
+         },
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0",
+            "File::Spec" : "0",
+            "IO::Handle" : "0",
+            "IPC::Open3" : "0",
+            "Test::More" : "0.94",
+            "Test::Warn" : "0",
+            "warnings" : "0"
+         }
+      }
+   },
+   "provides" : {
+      "Parallel::ForkManager" : {
+         "file" : "lib/Parallel/ForkManager.pm",
+         "version" : "1.17"
+      }
+   },
+   "release_status" : "stable",
+   "resources" : {
+      "bugtracker" : {
+         "web" : "https://github.com/dluxhu/perl-parallel-forkmanager/issues"
+      },
+      "homepage" : "https://github.com/dluxhu/perl-parallel-forkmanager",
+      "repository" : {
+         "type" : "git",
+         "url" : "https://github.com/dluxhu/perl-parallel-forkmanager.git",
+         "web" : "https://github.com/dluxhu/perl-parallel-forkmanager"
+      }
+   },
+   "version" : "1.17",
+   "x_authority" : "cpan:DLUX",
+   "x_contributors" : [
+      "Ninebit <kevin@9b.io>",
+      "Shlomi Fish <shlomif@shlomifish.org>"
+   ]
+}
diff --git a/Parallel-ForkManager-1.17/MYMETA.yml b/Parallel-ForkManager-1.17/MYMETA.yml
new file mode 100644 (file)
index 0000000..43f7e33
--- /dev/null
@@ -0,0 +1,45 @@
+---
+abstract: 'A simple parallel processing fork manager'
+author:
+  - 'dLux (Szabó, Balázs) <dlux@dlux.hu>'
+  - 'Yanick Champoux <yanick@cpan.org>'
+  - 'Gabor Szabo <gabor@szabgab.com>'
+build_requires:
+  ExtUtils::MakeMaker: 0
+  File::Spec: 0
+  IO::Handle: 0
+  IPC::Open3: 0
+  Test::More: 0.94
+  Test::Warn: 0
+  warnings: 0
+configure_requires:
+  ExtUtils::MakeMaker: 0
+dynamic_config: 0
+generated_by: 'Dist::Zilla version 5.040, CPAN::Meta::Converter version 2.150001, CPAN::Meta::Converter version 2.120921'
+license: perl
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: 1.4
+name: Parallel-ForkManager
+provides:
+  Parallel::ForkManager:
+    file: lib/Parallel/ForkManager.pm
+    version: 1.17
+requires:
+  Carp: 0
+  File::Path: 0
+  File::Spec: 0
+  File::Temp: 0
+  POSIX: 0
+  Storable: 0
+  perl: 5.006
+  strict: 0
+resources:
+  bugtracker: https://github.com/dluxhu/perl-parallel-forkmanager/issues
+  homepage: https://github.com/dluxhu/perl-parallel-forkmanager
+  repository: https://github.com/dluxhu/perl-parallel-forkmanager.git
+version: 1.17
+x_authority: cpan:DLUX
+x_contributors:
+  - 'Ninebit <kevin@9b.io>'
+  - 'Shlomi Fish <shlomif@shlomifish.org>'
diff --git a/Parallel-ForkManager-1.17/Makefile b/Parallel-ForkManager-1.17/Makefile
new file mode 100644 (file)
index 0000000..f8fa563
--- /dev/null
@@ -0,0 +1,877 @@
+# This Makefile is for the Parallel::ForkManager extension to perl.
+#
+# It was generated automatically by MakeMaker version
+# 6.66 (Revision: 66600) from the contents of
+# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
+#
+#       ANY CHANGES MADE HERE WILL BE LOST!
+#
+#   MakeMaker ARGV: ()
+#
+
+#   MakeMaker Parameters:
+
+#     ABSTRACT => q[A simple parallel processing fork manager]
+#     AUTHOR => [q[dLux (Szabó, Balázs) <dlux@dlux.hu>, Yanick Champoux <yanick@cpan.org>, Gabor Szabo <gabor@szabgab.com>]]
+#     BUILD_REQUIRES => {  }
+#     CONFIGURE_REQUIRES => { ExtUtils::MakeMaker=>q[0] }
+#     DISTNAME => q[Parallel-ForkManager]
+#     LICENSE => q[perl]
+#     MIN_PERL_VERSION => q[5.006]
+#     NAME => q[Parallel::ForkManager]
+#     PREREQ_PM => { Test::More=>q[0.94], File::Spec=>q[0], File::Path=>q[0], IO::Handle=>q[0], ExtUtils::MakeMaker=>q[0], POSIX=>q[0], warnings=>q[0], IPC::Open3=>q[0], strict=>q[0], Test::Warn=>q[0], Storable=>q[0], File::Temp=>q[0], Carp=>q[0] }
+#     TEST_REQUIRES => { ExtUtils::MakeMaker=>q[0], IO::Handle=>q[0], File::Spec=>q[0], Test::Warn=>q[0], Test::More=>q[0.94], IPC::Open3=>q[0], warnings=>q[0] }
+#     VERSION => q[1.17]
+#     test => { TESTS=>q[t/*.t] }
+
+# --- MakeMaker post_initialize section:
+
+
+# --- MakeMaker const_config section:
+
+# These definitions are from config.sh (via /usr/lib/perl/5.18/Config.pm).
+# They may have been overridden via Makefile.PL or on the command line.
+AR = ar
+CC = cc
+CCCDLFLAGS = -fPIC
+CCDLFLAGS = -Wl,-E
+DLEXT = so
+DLSRC = dl_dlopen.xs
+EXE_EXT = 
+FULL_AR = /usr/bin/ar
+LD = cc
+LDDLFLAGS = -shared -L/usr/local/lib -fstack-protector
+LDFLAGS =  -fstack-protector -L/usr/local/lib
+LIBC = 
+LIB_EXT = .a
+OBJ_EXT = .o
+OSNAME = linux
+OSVERS = 3.2.0-58-generic
+RANLIB = :
+SITELIBEXP = /usr/local/share/perl/5.18.2
+SITEARCHEXP = /usr/local/lib/perl/5.18.2
+SO = so
+VENDORARCHEXP = /usr/lib/perl5
+VENDORLIBEXP = /usr/share/perl5
+
+
+# --- MakeMaker constants section:
+AR_STATIC_ARGS = cr
+DIRFILESEP = /
+DFSEP = $(DIRFILESEP)
+NAME = Parallel::ForkManager
+NAME_SYM = Parallel_ForkManager
+VERSION = 1.17
+VERSION_MACRO = VERSION
+VERSION_SYM = 1_17
+DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
+XS_VERSION = 1.17
+XS_VERSION_MACRO = XS_VERSION
+XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
+INST_ARCHLIB = blib/arch
+INST_SCRIPT = blib/script
+INST_BIN = blib/bin
+INST_LIB = blib/lib
+INST_MAN1DIR = blib/man1
+INST_MAN3DIR = blib/man3
+MAN1EXT = 1p
+MAN3EXT = 3pm
+INSTALLDIRS = site
+DESTDIR = 
+PREFIX = /usr
+PERLPREFIX = $(PREFIX)
+SITEPREFIX = $(PREFIX)/local
+VENDORPREFIX = $(PREFIX)
+INSTALLPRIVLIB = $(PERLPREFIX)/share/perl/5.18
+DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
+INSTALLSITELIB = $(SITEPREFIX)/share/perl/5.18.2
+DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
+INSTALLVENDORLIB = $(VENDORPREFIX)/share/perl5
+DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
+INSTALLARCHLIB = $(PERLPREFIX)/lib/perl/5.18
+DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
+INSTALLSITEARCH = $(SITEPREFIX)/lib/perl/5.18.2
+DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
+INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5
+DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
+INSTALLBIN = $(PERLPREFIX)/bin
+DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
+INSTALLSITEBIN = $(SITEPREFIX)/bin
+DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
+INSTALLVENDORBIN = $(VENDORPREFIX)/bin
+DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
+INSTALLSCRIPT = $(PERLPREFIX)/bin
+DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
+INSTALLSITESCRIPT = $(SITEPREFIX)/bin
+DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT)
+INSTALLVENDORSCRIPT = $(VENDORPREFIX)/bin
+DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT)
+INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1
+DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
+INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1
+DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
+INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1
+DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
+INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3
+DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
+INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3
+DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
+INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3
+DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
+PERL_LIB = /usr/share/perl/5.18
+PERL_ARCHLIB = /usr/lib/perl/5.18
+LIBPERL_A = libperl.a
+FIRST_MAKEFILE = Makefile
+MAKEFILE_OLD = Makefile.old
+MAKE_APERL_FILE = Makefile.aperl
+PERLMAINCC = $(CC)
+PERL_INC = /usr/lib/perl/5.18/CORE
+PERL = /usr/bin/perl
+FULLPERL = /usr/bin/perl
+ABSPERL = $(PERL)
+PERLRUN = $(PERL)
+FULLPERLRUN = $(FULLPERL)
+ABSPERLRUN = $(ABSPERL)
+PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
+PERL_CORE = 0
+PERM_DIR = 755
+PERM_RW = 644
+PERM_RWX = 755
+
+MAKEMAKER   = /usr/share/perl/5.18/ExtUtils/MakeMaker.pm
+MM_VERSION  = 6.66
+MM_REVISION = 66600
+
+# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
+# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
+# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
+# DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
+MAKE = make
+FULLEXT = Parallel/ForkManager
+BASEEXT = ForkManager
+PARENT_NAME = Parallel
+DLBASE = $(BASEEXT)
+VERSION_FROM = 
+OBJECT = 
+LDFROM = $(OBJECT)
+LINKTYPE = dynamic
+BOOTDEP = 
+
+# Handy lists of source code files:
+XS_FILES = 
+C_FILES  = 
+O_FILES  = 
+H_FILES  = 
+MAN1PODS = 
+MAN3PODS = lib/Parallel/ForkManager.pm
+
+# Where is the Config information that we are using/depend on
+CONFIGDEP = $(PERL_ARCHLIB)$(DFSEP)Config.pm $(PERL_INC)$(DFSEP)config.h
+
+# Where to build things
+INST_LIBDIR      = $(INST_LIB)/Parallel
+INST_ARCHLIBDIR  = $(INST_ARCHLIB)/Parallel
+
+INST_AUTODIR     = $(INST_LIB)/auto/$(FULLEXT)
+INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
+
+INST_STATIC      = 
+INST_DYNAMIC     = 
+INST_BOOT        = 
+
+# Extra linker info
+EXPORT_LIST        = 
+PERL_ARCHIVE       = 
+PERL_ARCHIVE_AFTER = 
+
+
+TO_INST_PM = lib/Parallel/ForkManager.pm
+
+PM_TO_BLIB = lib/Parallel/ForkManager.pm \
+       blib/lib/Parallel/ForkManager.pm
+
+
+# --- MakeMaker platform_constants section:
+MM_Unix_VERSION = 6.66
+PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
+
+
+# --- MakeMaker tool_autosplit section:
+# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
+AUTOSPLITFILE = $(ABSPERLRUN)  -e 'use AutoSplit;  autosplit($$$$ARGV[0], $$$$ARGV[1], 0, 1, 1)' --
+
+
+
+# --- MakeMaker tool_xsubpp section:
+
+
+# --- MakeMaker tools_other section:
+SHELL = /bin/sh
+CHMOD = chmod
+CP = cp
+MV = mv
+NOOP = $(TRUE)
+NOECHO = @
+RM_F = rm -f
+RM_RF = rm -rf
+TEST_F = test -f
+TOUCH = touch
+UMASK_NULL = umask 0
+DEV_NULL = > /dev/null 2>&1
+MKPATH = $(ABSPERLRUN) -MExtUtils::Command -e 'mkpath' --
+EQUALIZE_TIMESTAMP = $(ABSPERLRUN) -MExtUtils::Command -e 'eqtime' --
+FALSE = false
+TRUE = true
+ECHO = echo
+ECHO_N = echo -n
+UNINST = 0
+VERBINST = 0
+MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install([ from_to => {@ARGV}, verbose => '\''$(VERBINST)'\'', uninstall_shadows => '\''$(UNINST)'\'', dir_mode => '\''$(PERM_DIR)'\'' ]);' --
+DOC_INSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'perllocal_install' --
+UNINSTALL = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'uninstall' --
+WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) -MExtUtils::Command::MM -e 'warn_if_old_packlist' --
+MACROSTART = 
+MACROEND = 
+USEMAKEFILE = -f
+FIXIN = $(ABSPERLRUN) -MExtUtils::MY -e 'MY->fixin(shift)' --
+
+
+# --- MakeMaker makemakerdflt section:
+makemakerdflt : all
+       $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dist section:
+TAR = tar
+TARFLAGS = cvf
+ZIP = zip
+ZIPFLAGS = -r
+COMPRESS = gzip --best
+SUFFIX = .gz
+SHAR = shar
+PREOP = $(NOECHO) $(NOOP)
+POSTOP = $(NOECHO) $(NOOP)
+TO_UNIX = $(NOECHO) $(NOOP)
+CI = ci -u
+RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
+DIST_CP = best
+DIST_DEFAULT = tardist
+DISTNAME = Parallel-ForkManager
+DISTVNAME = Parallel-ForkManager-1.17
+
+
+# --- MakeMaker macro section:
+
+
+# --- MakeMaker depend section:
+
+
+# --- MakeMaker cflags section:
+
+
+# --- MakeMaker const_loadlibs section:
+
+
+# --- MakeMaker const_cccmd section:
+
+
+# --- MakeMaker post_constants section:
+
+
+# --- MakeMaker pasthru section:
+
+PASTHRU = LIBPERL_A="$(LIBPERL_A)"\
+       LINKTYPE="$(LINKTYPE)"\
+       LD="$(LD)"\
+       PREFIX="$(PREFIX)"
+
+
+# --- MakeMaker special_targets section:
+.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
+
+.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir
+
+
+
+# --- MakeMaker c_o section:
+
+
+# --- MakeMaker xs_c section:
+
+
+# --- MakeMaker xs_o section:
+
+
+# --- MakeMaker top_targets section:
+all :: pure_all manifypods
+       $(NOECHO) $(NOOP)
+
+
+pure_all :: config pm_to_blib subdirs linkext
+       $(NOECHO) $(NOOP)
+
+subdirs :: $(MYEXTLIB)
+       $(NOECHO) $(NOOP)
+
+config :: $(FIRST_MAKEFILE) blibdirs
+       $(NOECHO) $(NOOP)
+
+help :
+       perldoc ExtUtils::MakeMaker
+
+
+# --- MakeMaker blibdirs section:
+blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists
+       $(NOECHO) $(NOOP)
+
+# Backwards compat with 6.18 through 6.25
+blibdirs.ts : blibdirs
+       $(NOECHO) $(NOOP)
+
+$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_LIBDIR)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_LIBDIR)
+       $(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists
+
+$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_ARCHLIB)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHLIB)
+       $(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists
+
+$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_AUTODIR)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_AUTODIR)
+       $(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists
+
+$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_ARCHAUTODIR)
+       $(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists
+
+$(INST_BIN)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_BIN)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_BIN)
+       $(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists
+
+$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_SCRIPT)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_SCRIPT)
+       $(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists
+
+$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_MAN1DIR)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN1DIR)
+       $(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists
+
+$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL
+       $(NOECHO) $(MKPATH) $(INST_MAN3DIR)
+       $(NOECHO) $(CHMOD) $(PERM_DIR) $(INST_MAN3DIR)
+       $(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists
+
+
+
+# --- MakeMaker linkext section:
+
+linkext :: $(LINKTYPE)
+       $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dlsyms section:
+
+
+# --- MakeMaker dynamic section:
+
+dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
+       $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker dynamic_bs section:
+
+BOOTSTRAP =
+
+
+# --- MakeMaker dynamic_lib section:
+
+
+# --- MakeMaker static section:
+
+## $(INST_PM) has been moved to the all: target.
+## It remains here for awhile to allow for old usage: "make static"
+static :: $(FIRST_MAKEFILE) $(INST_STATIC)
+       $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker static_lib section:
+
+
+# --- MakeMaker manifypods section:
+
+POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
+POD2MAN = $(POD2MAN_EXE)
+
+
+manifypods : pure_all  \
+       lib/Parallel/ForkManager.pm
+       $(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) \
+         lib/Parallel/ForkManager.pm $(INST_MAN3DIR)/Parallel::ForkManager.$(MAN3EXT) 
+
+
+
+
+# --- MakeMaker processPL section:
+
+
+# --- MakeMaker installbin section:
+
+
+# --- MakeMaker subdirs section:
+
+# none
+
+# --- MakeMaker clean_subdirs section:
+clean_subdirs :
+       $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker clean section:
+
+# Delete temporary files but do not touch installed files. We don't delete
+# the Makefile here so a later make realclean still has a makefile to use.
+
+clean :: clean_subdirs
+       - $(RM_F) \
+         perlmain.c core.[0-9][0-9] \
+         $(BASEEXT).bso perl.exe \
+         core.[0-9] $(MAKE_APERL_FILE) \
+         pm_to_blib core.[0-9][0-9][0-9][0-9][0-9] \
+         $(BASEEXT).def tmon.out \
+         MYMETA.yml core.[0-9][0-9][0-9] \
+         $(BASEEXT).exp *$(LIB_EXT) \
+         pm_to_blib.ts perl \
+         *$(OBJ_EXT) lib$(BASEEXT).def \
+         blibdirs.ts core.[0-9][0-9][0-9][0-9] \
+         $(INST_ARCHAUTODIR)/extralibs.all MYMETA.json \
+         core.*perl.*.? core \
+         $(INST_ARCHAUTODIR)/extralibs.ld $(BASEEXT).x \
+         mon.out *perl.core \
+         $(BOOTSTRAP) so_locations \
+         perl$(EXE_EXT) 
+       - $(RM_RF) \
+         blib 
+       - $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
+
+
+# --- MakeMaker realclean_subdirs section:
+realclean_subdirs :
+       $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker realclean section:
+# Delete temporary files (via clean) and also delete dist files
+realclean purge ::  clean realclean_subdirs
+       - $(RM_F) \
+         $(FIRST_MAKEFILE) $(MAKEFILE_OLD) 
+       - $(RM_RF) \
+         $(DISTVNAME) 
+
+
+# --- MakeMaker metafile section:
+metafile : create_distdir
+       $(NOECHO) $(ECHO) Generating META.yml
+       $(NOECHO) $(ECHO) '---' > META_new.yml
+       $(NOECHO) $(ECHO) 'abstract: '\''A simple parallel processing fork manager'\''' >> META_new.yml
+       $(NOECHO) $(ECHO) 'author:' >> META_new.yml
+       $(NOECHO) $(ECHO) '  - '\''dLux (Szabó, Balázs) <dlux@dlux.hu>, Yanick Champoux <yanick@cpan.org>, Gabor Szabo <gabor@szabgab.com>'\''' >> META_new.yml
+       $(NOECHO) $(ECHO) 'build_requires:' >> META_new.yml
+       $(NOECHO) $(ECHO) '  ExtUtils::MakeMaker: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  File::Spec: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  IO::Handle: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  IPC::Open3: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  Test::More: 0.94' >> META_new.yml
+       $(NOECHO) $(ECHO) '  Test::Warn: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  warnings: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) 'configure_requires:' >> META_new.yml
+       $(NOECHO) $(ECHO) '  ExtUtils::MakeMaker: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) 'dynamic_config: 1' >> META_new.yml
+       $(NOECHO) $(ECHO) 'generated_by: '\''ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921'\''' >> META_new.yml
+       $(NOECHO) $(ECHO) 'license: perl' >> META_new.yml
+       $(NOECHO) $(ECHO) 'meta-spec:' >> META_new.yml
+       $(NOECHO) $(ECHO) '  url: http://module-build.sourceforge.net/META-spec-v1.4.html' >> META_new.yml
+       $(NOECHO) $(ECHO) '  version: 1.4' >> META_new.yml
+       $(NOECHO) $(ECHO) 'name: Parallel-ForkManager' >> META_new.yml
+       $(NOECHO) $(ECHO) 'no_index:' >> META_new.yml
+       $(NOECHO) $(ECHO) '  directory:' >> META_new.yml
+       $(NOECHO) $(ECHO) '    - t' >> META_new.yml
+       $(NOECHO) $(ECHO) '    - inc' >> META_new.yml
+       $(NOECHO) $(ECHO) 'requires:' >> META_new.yml
+       $(NOECHO) $(ECHO) '  Carp: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  File::Path: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  File::Spec: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  File::Temp: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  POSIX: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  Storable: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) '  perl: 5.006' >> META_new.yml
+       $(NOECHO) $(ECHO) '  strict: 0' >> META_new.yml
+       $(NOECHO) $(ECHO) 'version: 1.17' >> META_new.yml
+       -$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml
+       $(NOECHO) $(ECHO) Generating META.json
+       $(NOECHO) $(ECHO) '{' > META_new.json
+       $(NOECHO) $(ECHO) '   "abstract" : "A simple parallel processing fork manager",' >> META_new.json
+       $(NOECHO) $(ECHO) '   "author" : [' >> META_new.json
+       $(NOECHO) $(ECHO) '      "dLux (Szabó, Balázs) <dlux@dlux.hu>, Yanick Champoux <yanick@cpan.org>, Gabor Szabo <gabor@szabgab.com>"' >> META_new.json
+       $(NOECHO) $(ECHO) '   ],' >> META_new.json
+       $(NOECHO) $(ECHO) '   "dynamic_config" : 1,' >> META_new.json
+       $(NOECHO) $(ECHO) '   "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921",' >> META_new.json
+       $(NOECHO) $(ECHO) '   "license" : [' >> META_new.json
+       $(NOECHO) $(ECHO) '      "perl_5"' >> META_new.json
+       $(NOECHO) $(ECHO) '   ],' >> META_new.json
+       $(NOECHO) $(ECHO) '   "meta-spec" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",' >> META_new.json
+       $(NOECHO) $(ECHO) '      "version" : "2"' >> META_new.json
+       $(NOECHO) $(ECHO) '   },' >> META_new.json
+       $(NOECHO) $(ECHO) '   "name" : "Parallel-ForkManager",' >> META_new.json
+       $(NOECHO) $(ECHO) '   "no_index" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '      "directory" : [' >> META_new.json
+       $(NOECHO) $(ECHO) '         "t",' >> META_new.json
+       $(NOECHO) $(ECHO) '         "inc"' >> META_new.json
+       $(NOECHO) $(ECHO) '      ]' >> META_new.json
+       $(NOECHO) $(ECHO) '   },' >> META_new.json
+       $(NOECHO) $(ECHO) '   "prereqs" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '      "build" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '         "requires" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '            "ExtUtils::MakeMaker" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "File::Spec" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "IO::Handle" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "IPC::Open3" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "Test::More" : "0.94",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "Test::Warn" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "warnings" : "0"' >> META_new.json
+       $(NOECHO) $(ECHO) '         }' >> META_new.json
+       $(NOECHO) $(ECHO) '      },' >> META_new.json
+       $(NOECHO) $(ECHO) '      "configure" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '         "requires" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '            "ExtUtils::MakeMaker" : "0"' >> META_new.json
+       $(NOECHO) $(ECHO) '         }' >> META_new.json
+       $(NOECHO) $(ECHO) '      },' >> META_new.json
+       $(NOECHO) $(ECHO) '      "runtime" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '         "requires" : {' >> META_new.json
+       $(NOECHO) $(ECHO) '            "Carp" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "File::Path" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "File::Spec" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "File::Temp" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "POSIX" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "Storable" : "0",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "perl" : "5.006",' >> META_new.json
+       $(NOECHO) $(ECHO) '            "strict" : "0"' >> META_new.json
+       $(NOECHO) $(ECHO) '         }' >> META_new.json
+       $(NOECHO) $(ECHO) '      }' >> META_new.json
+       $(NOECHO) $(ECHO) '   },' >> META_new.json
+       $(NOECHO) $(ECHO) '   "release_status" : "stable",' >> META_new.json
+       $(NOECHO) $(ECHO) '   "version" : "1.17"' >> META_new.json
+       $(NOECHO) $(ECHO) '}' >> META_new.json
+       -$(NOECHO) $(MV) META_new.json $(DISTVNAME)/META.json
+
+
+# --- MakeMaker signature section:
+signature :
+       cpansign -s
+
+
+# --- MakeMaker dist_basics section:
+distclean :: realclean distcheck
+       $(NOECHO) $(NOOP)
+
+distcheck :
+       $(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
+
+skipcheck :
+       $(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
+
+manifest :
+       $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
+
+veryclean : realclean
+       $(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old 
+
+
+
+# --- MakeMaker dist_core section:
+
+dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
+       $(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
+         -e '    if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';' --
+
+tardist : $(DISTVNAME).tar$(SUFFIX)
+       $(NOECHO) $(NOOP)
+
+uutardist : $(DISTVNAME).tar$(SUFFIX)
+       uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
+
+$(DISTVNAME).tar$(SUFFIX) : distdir
+       $(PREOP)
+       $(TO_UNIX)
+       $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
+       $(RM_RF) $(DISTVNAME)
+       $(COMPRESS) $(DISTVNAME).tar
+       $(POSTOP)
+
+zipdist : $(DISTVNAME).zip
+       $(NOECHO) $(NOOP)
+
+$(DISTVNAME).zip : distdir
+       $(PREOP)
+       $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
+       $(RM_RF) $(DISTVNAME)
+       $(POSTOP)
+
+shdist : distdir
+       $(PREOP)
+       $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
+       $(RM_RF) $(DISTVNAME)
+       $(POSTOP)
+
+
+# --- MakeMaker distdir section:
+create_distdir :
+       $(RM_RF) $(DISTVNAME)
+       $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
+               -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
+
+distdir : create_distdir distmeta 
+       $(NOECHO) $(NOOP)
+
+
+
+# --- MakeMaker dist_test section:
+disttest : distdir
+       cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL 
+       cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
+       cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
+
+
+
+# --- MakeMaker dist_ci section:
+
+ci :
+       $(PERLRUN) "-MExtUtils::Manifest=maniread" \
+         -e "@all = keys %{ maniread() };" \
+         -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
+         -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"
+
+
+# --- MakeMaker distmeta section:
+distmeta : create_distdir metafile
+       $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -e q{META.yml};' \
+         -e 'eval { maniadd({q{META.yml} => q{Module YAML meta-data (added by MakeMaker)}}) }' \
+         -e '    or print "Could not add META.yml to MANIFEST: $$$${'\''@'\''}\n"' --
+       $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'exit unless -f q{META.json};' \
+         -e 'eval { maniadd({q{META.json} => q{Module JSON meta-data (added by MakeMaker)}}) }' \
+         -e '    or print "Could not add META.json to MANIFEST: $$$${'\''@'\''}\n"' --
+
+
+
+# --- MakeMaker distsignature section:
+distsignature : create_distdir
+       $(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) } ' \
+         -e '    or print "Could not add SIGNATURE to MANIFEST: $$$${'\''@'\''}\n"' --
+       $(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE
+       cd $(DISTVNAME) && cpansign -s
+
+
+
+# --- MakeMaker install section:
+
+install :: pure_install doc_install
+       $(NOECHO) $(NOOP)
+
+install_perl :: pure_perl_install doc_perl_install
+       $(NOECHO) $(NOOP)
+
+install_site :: pure_site_install doc_site_install
+       $(NOECHO) $(NOOP)
+
+install_vendor :: pure_vendor_install doc_vendor_install
+       $(NOECHO) $(NOOP)
+
+pure_install :: pure_$(INSTALLDIRS)_install
+       $(NOECHO) $(NOOP)
+
+doc_install :: doc_$(INSTALLDIRS)_install
+       $(NOECHO) $(NOOP)
+
+pure__install : pure_site_install
+       $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+doc__install : doc_site_install
+       $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
+
+pure_perl_install :: all
+       $(NOECHO) umask 022; $(MOD_INSTALL) \
+               $(INST_LIB) $(DESTINSTALLPRIVLIB) \
+               $(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \
+               $(INST_BIN) $(DESTINSTALLBIN) \
+               $(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
+               $(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \
+               $(INST_MAN3DIR) $(DESTINSTALLMAN3DIR)
+       $(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+               $(SITEARCHEXP)/auto/$(FULLEXT)
+
+
+pure_site_install :: all
+       $(NOECHO) umask 02; $(MOD_INSTALL) \
+               read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \
+               write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \
+               $(INST_LIB) $(DESTINSTALLSITELIB) \
+               $(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \
+               $(INST_BIN) $(DESTINSTALLSITEBIN) \
+               $(INST_SCRIPT) $(DESTINSTALLSITESCRIPT) \
+               $(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \
+               $(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR)
+       $(NOECHO) $(WARN_IF_OLD_PACKLIST) \
+               $(PERL_ARCHLIB)/auto/$(FULLEXT)
+
+pure_vendor_install :: all
+       $(NOECHO) umask 022; $(MOD_INSTALL) \
+               $(INST_LIB) $(DESTINSTALLVENDORLIB) \
+               $(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \
+               $(INST_BIN) $(DESTINSTALLVENDORBIN) \
+               $(INST_SCRIPT) $(DESTINSTALLVENDORSCRIPT) \
+               $(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \
+               $(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR)
+
+doc_perl_install :: all
+
+doc_site_install :: all
+       $(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLSITEARCH)/perllocal.pod
+       -$(NOECHO) umask 02; $(MKPATH) $(DESTINSTALLSITEARCH)
+       -$(NOECHO) umask 02; $(DOC_INSTALL) \
+               "Module" "$(NAME)" \
+               "installed into" "$(INSTALLSITELIB)" \
+               LINKTYPE "$(LINKTYPE)" \
+               VERSION "$(VERSION)" \
+               EXE_FILES "$(EXE_FILES)" \
+               >> $(DESTINSTALLSITEARCH)/perllocal.pod
+
+doc_vendor_install :: all
+
+
+uninstall :: uninstall_from_$(INSTALLDIRS)dirs
+       $(NOECHO) $(NOOP)
+
+uninstall_from_perldirs ::
+
+uninstall_from_sitedirs ::
+       $(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist
+
+uninstall_from_vendordirs ::
+
+
+
+# --- MakeMaker force section:
+# Phony target to force checking subdirectories.
+FORCE :
+       $(NOECHO) $(NOOP)
+
+
+# --- MakeMaker perldepend section:
+
+
+# --- MakeMaker makefile section:
+# We take a very conservative approach here, but it's worth it.
+# We move Makefile to Makefile.old here to avoid gnu make looping.
+$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
+       $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
+       $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
+       -$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
+       -$(NOECHO) $(MV)   $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
+       - $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL)
+       $(PERLRUN) Makefile.PL 
+       $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
+       $(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command.  <=="
+       $(FALSE)
+
+
+
+# --- MakeMaker staticmake section:
+
+# --- MakeMaker makeaperl section ---
+MAP_TARGET    = perl
+FULLPERL      = /usr/bin/perl
+
+$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
+       $(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@
+
+$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib
+       $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
+       $(NOECHO) $(PERLRUNINST) \
+               Makefile.PL DIR= \
+               MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
+               MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
+
+
+# --- MakeMaker test section:
+
+TEST_VERBOSE=0
+TEST_TYPE=test_$(LINKTYPE)
+TEST_FILE = test.pl
+TEST_FILES = t/*.t
+TESTDB_SW = -d
+
+testdb :: testdb_$(LINKTYPE)
+
+test :: $(TEST_TYPE) subdirs-test
+
+subdirs-test ::
+       $(NOECHO) $(NOOP)
+
+
+test_dynamic :: pure_all
+       PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-MExtUtils::Command::MM" "-e" "test_harness($(TEST_VERBOSE), '$(INST_LIB)', '$(INST_ARCHLIB)')" $(TEST_FILES)
+
+testdb_dynamic :: pure_all
+       PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
+
+test_ : test_dynamic
+
+test_static :: test_dynamic
+testdb_static :: testdb_dynamic
+
+
+# --- MakeMaker ppd section:
+# Creates a PPD (Perl Package Description) for a binary distribution.
+ppd :
+       $(NOECHO) $(ECHO) '<SOFTPKG NAME="$(DISTNAME)" VERSION="$(VERSION)">' > $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '    <ABSTRACT>A simple parallel processing fork manager</ABSTRACT>' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '    <AUTHOR>dLux (Szabó, Balázs) &lt;dlux@dlux.hu&gt;, Yanick Champoux &lt;yanick@cpan.org&gt;, Gabor Szabo &lt;gabor@szabgab.com&gt;</AUTHOR>' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '    <IMPLEMENTATION>' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <PERLCORE VERSION="5,006,0,0" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <REQUIRE NAME="Carp::" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <REQUIRE NAME="File::Path" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <REQUIRE NAME="File::Spec" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <REQUIRE NAME="File::Temp" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <REQUIRE NAME="POSIX::" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <REQUIRE NAME="Storable::" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <REQUIRE NAME="strict::" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <ARCHITECTURE NAME="x86_64-linux-gnu-thread-multi-5.18" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '        <CODEBASE HREF="" />' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '    </IMPLEMENTATION>' >> $(DISTNAME).ppd
+       $(NOECHO) $(ECHO) '</SOFTPKG>' >> $(DISTNAME).ppd
+
+
+# --- MakeMaker pm_to_blib section:
+
+pm_to_blib : $(FIRST_MAKEFILE) $(TO_INST_PM)
+       $(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', q[$(PM_FILTER)], '\''$(PERM_DIR)'\'')' -- \
+         lib/Parallel/ForkManager.pm blib/lib/Parallel/ForkManager.pm 
+       $(NOECHO) $(TOUCH) pm_to_blib
+
+
+# --- MakeMaker selfdocument section:
+
+
+# --- MakeMaker postamble section:
+
+
+# End.
diff --git a/Parallel-ForkManager-1.17/Makefile.PL b/Parallel-ForkManager-1.17/Makefile.PL
new file mode 100644 (file)
index 0000000..49c827c
--- /dev/null
@@ -0,0 +1,70 @@
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.040.
+use strict;
+use warnings;
+
+use 5.006;
+
+use ExtUtils::MakeMaker;
+
+my %WriteMakefileArgs = (
+  "ABSTRACT" => "A simple parallel processing fork manager",
+  "AUTHOR" => "dLux (Szab\x{f3}, Bal\x{e1}zs) <dlux\@dlux.hu>, Yanick Champoux <yanick\@cpan.org>, Gabor Szabo <gabor\@szabgab.com>",
+  "CONFIGURE_REQUIRES" => {
+    "ExtUtils::MakeMaker" => 0
+  },
+  "DISTNAME" => "Parallel-ForkManager",
+  "LICENSE" => "perl",
+  "MIN_PERL_VERSION" => "5.006",
+  "NAME" => "Parallel::ForkManager",
+  "PREREQ_PM" => {
+    "Carp" => 0,
+    "File::Path" => 0,
+    "File::Spec" => 0,
+    "File::Temp" => 0,
+    "POSIX" => 0,
+    "Storable" => 0,
+    "strict" => 0
+  },
+  "TEST_REQUIRES" => {
+    "ExtUtils::MakeMaker" => 0,
+    "File::Spec" => 0,
+    "IO::Handle" => 0,
+    "IPC::Open3" => 0,
+    "Test::More" => "0.94",
+    "Test::Warn" => 0,
+    "warnings" => 0
+  },
+  "VERSION" => "1.17",
+  "test" => {
+    "TESTS" => "t/*.t"
+  }
+);
+
+
+my %FallbackPrereqs = (
+  "Carp" => 0,
+  "ExtUtils::MakeMaker" => 0,
+  "File::Path" => 0,
+  "File::Spec" => 0,
+  "File::Temp" => 0,
+  "IO::Handle" => 0,
+  "IPC::Open3" => 0,
+  "POSIX" => 0,
+  "Storable" => 0,
+  "Test::More" => "0.94",
+  "Test::Warn" => 0,
+  "strict" => 0,
+  "warnings" => 0
+);
+
+
+unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
+  delete $WriteMakefileArgs{TEST_REQUIRES};
+  delete $WriteMakefileArgs{BUILD_REQUIRES};
+  $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
+}
+
+delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
+  unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
+
+WriteMakefile(%WriteMakefileArgs);
diff --git a/Parallel-ForkManager-1.17/README.mkdn b/Parallel-ForkManager-1.17/README.mkdn
new file mode 100644 (file)
index 0000000..95320a3
--- /dev/null
@@ -0,0 +1,537 @@
+# NAME
+
+Parallel::ForkManager - A simple parallel processing fork manager
+
+# VERSION
+
+version 1.17
+
+# SYNOPSIS
+
+    use Parallel::ForkManager;
+
+    my $pm = Parallel::ForkManager->new($MAX_PROCESSES);
+
+    DATA_LOOP:
+    foreach my $data (@all_data) {
+      # Forks and returns the pid for the child:
+      my $pid = $pm->start and next DATA_LOOP;
+
+      ... do some work with $data in the child process ...
+
+      $pm->finish; # Terminates the child process
+    }
+
+# DESCRIPTION
+
+This module is intended for use in operations that can be done in parallel
+where the number of processes to be forked off should be limited. Typical
+use is a downloader which will be retrieving hundreds/thousands of files.
+
+The code for a downloader would look something like this:
+
+    use LWP::Simple;
+    use Parallel::ForkManager;
+
+    ...
+
+    my @links=(
+      ["http://www.foo.bar/rulez.data","rulez_data.txt"],
+      ["http://new.host/more_data.doc","more_data.doc"],
+      ...
+    );
+
+    ...
+
+    # Max 30 processes for parallel download
+    my $pm = Parallel::ForkManager->new(30);
+
+    LINKS:
+    foreach my $linkarray (@links) {
+      $pm->start and next LINKS; # do the fork
+
+      my ($link, $fn) = @$linkarray;
+      warn "Cannot get $fn from $link"
+        if getstore($link, $fn) != RC_OK;
+
+      $pm->finish; # do the exit in the child process
+    }
+    $pm->wait_all_children;
+
+First you need to instantiate the ForkManager with the "new" constructor.
+You must specify the maximum number of processes to be created. If you
+specify 0, then NO fork will be done; this is good for debugging purposes.
+
+Next, use $pm->start to do the fork. $pm returns 0 for the child process,
+and child pid for the parent process (see also ["fork()" in perlfunc(1p)](http://man.he.net/man1p/perlfunc)).
+The "and next" skips the internal loop in the parent process. NOTE:
+$pm->start dies if the fork fails.
+
+$pm->finish terminates the child process (assuming a fork was done in the
+"start").
+
+NOTE: You cannot use $pm->start if you are already in the child process.
+If you want to manage another set of subprocesses in the child process,
+you must instantiate another Parallel::ForkManager object!
+
+# METHODS
+
+The comment letter indicates where the method should be run. P for parent,
+C for child.
+
+- new $processes
+
+    Instantiate a new Parallel::ForkManager object. You must specify the maximum
+    number of children to fork off. If you specify 0 (zero), then no children
+    will be forked. This is intended for debugging purposes.
+
+    The optional second parameter, $tempdir, is only used if you want the
+    children to send back a reference to some data (see RETRIEVING DATASTRUCTURES
+    below). If not provided, it is set via a call to [File::Temp](https://metacpan.org/pod/File::Temp)::tempdir().
+
+    The new method will die if the temporary directory does not exist or it is not
+    a directory.
+
+- start \[ $process\_identifier \]
+
+    This method does the fork. It returns the pid of the child process for
+    the parent, and 0 for the child process. If the $processes parameter
+    for the constructor is 0 then, assuming you're in the child process,
+    $pm->start simply returns 0.
+
+    An optional $process\_identifier can be provided to this method... It is used by
+    the "run\_on\_finish" callback (see CALLBACKS) for identifying the finished
+    process.
+
+- finish \[ $exit\_code \[, $data\_structure\_reference\] \]
+
+    Closes the child process by exiting and accepts an optional exit code
+    (default exit code is 0) which can be retrieved in the parent via callback.
+    If the second optional parameter is provided, the child attempts to send
+    it's contents back to the parent. If you use the program in debug mode
+    ($processes == 0), this method just calls the callback.
+
+    If the $data\_structure\_reference is provided, then it is serialized and
+    passed to the parent process. See RETRIEVING DATASTRUCTURES for more info.
+
+- set\_max\_procs $processes
+
+    Allows you to set a new maximum number of children to maintain.
+
+- wait\_all\_children
+
+    You can call this method to wait for all the processes which have been
+    forked. This is a blocking wait.
+
+- reap\_finished\_children
+
+    This is a non-blocking call to reap children and execute callbacks independent
+    of calls to "start" or "wait\_all\_children". Use this in scenarios where "start"
+    is called infrequently but you would like the callbacks executed quickly.
+
+- is\_parent
+
+    Returns `true` if within the parent or `false` if within the child.
+
+- is\_child
+
+    Returns `true` if within the child or `false` if within the parent.
+
+- max\_procs 
+
+    Returns the maximal number of processes the object will fork.
+
+- running\_procs
+
+    Returns the pids of the forked processes currently monitored by the
+    `Parallel::ForkManager`. Note that children are still reported as running
+    until the fork manager harvest them, via the next call to
+    `start` or `wait_all_children`.
+
+        my @pids = $pm->running_procs;
+
+        my $nbr_children =- $pm->running_procs;
+
+- wait\_for\_available\_procs( $n )
+
+    Wait until `$n` available process slots are available.
+    If `$n` is not given, defaults to _1_.
+
+- waitpid\_blocking\_sleep 
+
+    Returns the sleep period, in seconds, of the pseudo-blocking calls. The sleep
+    period can be a fraction of second. 
+
+    Returns `0` if disabled. 
+
+    Defaults to 1 second.
+
+    See _BLOCKING CALLS_ for more details.
+
+- set\_waitpid\_blocking\_sleep $seconds
+
+    Sets the the sleep period, in seconds, of the pseudo-blocking calls.
+    Set to `0` to disable.
+
+    See _BLOCKING CALLS_ for more details.
+
+# CALLBACKS
+
+You can define callbacks in the code, which are called on events like starting
+a process or upon finish. Declare these before the first call to start().
+
+The callbacks can be defined with the following methods:
+
+- run\_on\_finish $code \[, $pid \]
+
+    You can define a subroutine which is called when a child is terminated. It is
+    called in the parent process.
+
+    The parameters of the $code are the following:
+
+        - pid of the process, which is terminated
+        - exit code of the program
+        - identification of the process (if provided in the "start" method)
+        - exit signal (0-127: signal name)
+        - core dump (1 if there was core dump at exit)
+        - datastructure reference or undef (see RETRIEVING DATASTRUCTURES)
+
+- run\_on\_start $code
+
+    You can define a subroutine which is called when a child is started. It called
+    after the successful startup of a child in the parent process.
+
+    The parameters of the $code are the following:
+
+        - pid of the process which has been started
+        - identification of the process (if provided in the "start" method)
+
+- run\_on\_wait $code, \[$period\]
+
+    You can define a subroutine which is called when the child process needs to wait
+    for the startup. If $period is not defined, then one call is done per
+    child. If $period is defined, then $code is called periodically and the
+    module waits for $period seconds between the two calls. Note, $period can be
+    fractional number also. The exact "$period seconds" is not guaranteed,
+    signals can shorten and the process scheduler can make it longer (on busy
+    systems).
+
+    The $code called in the "start" and the "wait\_all\_children" method also.
+
+    No parameters are passed to the $code on the call.
+
+# BLOCKING CALLS
+
+When it comes to waiting for child processes to terminate, `Parallel::ForkManager` is between 
+a fork and a hard place (if you excuse the terrible pun). The underlying Perl `waitpid` function
+that the module relies on can block until either one specific or any child process 
+terminate, but not for a process part of a given group.
+
+This means that the module can do one of two things when it waits for 
+one of its child processes to terminate:
+
+- Only wait for its own child processes
+
+    This is done via a loop using a `waitpid` non-blocking call and a sleep statement.
+    The code does something along the lines of
+
+        while(1) {
+            if ( any of the P::FM child process terminated ) {
+                return its pid
+            }
+
+            sleep $sleep_period
+        }
+
+    This is the default behavior that the module will use.
+    This is not the most efficient way to wait for child processes, but it's
+    the safest way to ensure that `Parallel::ForkManager` won't interfere with 
+    any other part of the codebase. 
+
+    The sleep period is set via the method `set_waitpid_blocking_sleep`.
+
+- Block until any process terminate
+
+    Alternatively, `Parallel::ForkManager` can call `waitpid` such that it will
+    block until any child process terminate. If the child process was not one of
+    the monitored subprocesses, the wait will resume. This is more efficient, but mean
+    that `P::FM` can captures (and discards) the termination notification that a different
+    part of the code might be waiting for. 
+
+    If this is a race condition
+    that doesn't apply to your codebase, you can set the 
+    _waitpid\_blocking\_sleep_ period to `0`, which will enable `waitpid` call blocking.
+
+        my $pm = Parallel::ForkManager->new( 4 );
+
+        $pm->set_waitpid_blocking_sleep(0);  # true blocking calls enabled
+
+        for ( 1..100 ) {
+            $pm->start and next;
+
+            ...; # do work
+
+            $pm->finish;
+        }
+
+# RETRIEVING DATASTRUCTURES from child processes
+
+The ability for the parent to retrieve data structures is new as of version
+0.7.6.
+
+Each child process may optionally send 1 data structure back to the parent.
+By data structure, we mean a reference to a string, hash or array. The
+contents of the data structure are written out to temporary files on disc
+using the [Storable](https://metacpan.org/pod/Storable) modules' store() method. The reference is then
+retrieved from within the code you send to the run\_on\_finish callback.
+
+The data structure can be any scalar perl data structure which makes sense:
+string, numeric value or a reference to an array, hash or object.
+
+There are 2 steps involved in retrieving data structures:
+
+1) A reference to the data structure the child wishes to send back to the
+parent is provided as the second argument to the finish() call. It is up
+to the child to decide whether or not to send anything back to the parent.
+
+2) The data structure reference is retrieved using the callback provided in
+the run\_on\_finish() method.
+
+Keep in mind that data structure retrieval is not the same as returning a
+data structure from a method call. That is not what actually occurs. The
+data structure referenced in a given child process is serialized and
+written out to a file by [Storable](https://metacpan.org/pod/Storable). The file is subsequently read back
+into memory and a new data structure belonging to the parent process is
+created. Please consider the performance penality it can imply, so try to
+keep the returned structure small.
+
+# EXAMPLES
+
+## Parallel get
+
+This small example can be used to get URLs in parallel.
+
+    use Parallel::ForkManager;
+    use LWP::Simple;
+
+    my $pm = Parallel::ForkManager->new(10);
+
+    LINKS:
+    for my $link (@ARGV) {
+      $pm->start and next LINKS;
+      my ($fn) = $link =~ /^.*\/(.*?)$/;
+      if (!$fn) {
+        warn "Cannot determine filename from $fn\n";
+      } else {
+        $0 .= " " . $fn;
+        print "Getting $fn from $link\n";
+        my $rc = getstore($link, $fn);
+        print "$link downloaded. response code: $rc\n";
+      };
+      $pm->finish;
+    };
+
+## Callbacks
+
+Example of a program using callbacks to get child exit codes:
+
+    use strict;
+    use Parallel::ForkManager;
+
+    my $max_procs = 5;
+    my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara );
+    # hash to resolve PID's back to child specific information
+
+    my $pm = Parallel::ForkManager->new($max_procs);
+
+    # Setup a callback for when a child finishes up so we can
+    # get it's exit code
+    $pm->run_on_finish( sub {
+        my ($pid, $exit_code, $ident) = @_;
+        print "** $ident just got out of the pool ".
+          "with PID $pid and exit code: $exit_code\n";
+    });
+
+    $pm->run_on_start( sub {
+        my ($pid, $ident)=@_;
+        print "** $ident started, pid: $pid\n";
+    });
+
+    $pm->run_on_wait( sub {
+        print "** Have to wait for one children ...\n"
+      },
+      0.5
+    );
+
+    NAMES:
+    foreach my $child ( 0 .. $#names ) {
+      my $pid = $pm->start($names[$child]) and next NAMES;
+
+      # This code is the child process
+      print "This is $names[$child], Child number $child\n";
+      sleep ( 2 * $child );
+      print "$names[$child], Child $child is about to get out...\n";
+      sleep 1;
+      $pm->finish($child); # pass an exit code to finish
+    }
+
+    print "Waiting for Children...\n";
+    $pm->wait_all_children;
+    print "Everybody is out of the pool!\n";
+
+## Data structure retrieval
+
+In this simple example, each child sends back a string reference.
+
+    use Parallel::ForkManager 0.7.6;
+    use strict;
+
+    my $pm = Parallel::ForkManager->new(2, '/server/path/to/temp/dir/');
+
+    # data structure retrieval and handling
+    $pm -> run_on_finish ( # called BEFORE the first call to start()
+      sub {
+        my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+
+        # retrieve data structure from child
+        if (defined($data_structure_reference)) {  # children are not forced to send anything
+          my $string = ${$data_structure_reference};  # child passed a string reference
+          print "$string\n";
+        }
+        else {  # problems occuring during storage or retrieval will throw a warning
+          print qq|No message received from child process $pid!\n|;
+        }
+      }
+    );
+
+    # prep random statement components
+    my @foods = ('chocolate', 'ice cream', 'peanut butter', 'pickles', 'pizza', 'bacon', 'pancakes', 'spaghetti', 'cookies');
+    my @preferences = ('loves', q|can't stand|, 'always wants more', 'will walk 100 miles for', 'only eats', 'would starve rather than eat');
+
+    # run the parallel processes
+    PERSONS:
+    foreach my $person (qw(Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry)) {
+      $pm->start() and next PERSONS;
+
+      # generate a random statement about food preferences
+      my $statement = $person . ' ' . $preferences[int(rand @preferences)] . ' ' . $foods[int(rand @foods)];
+
+      # send it back to the parent process
+      $pm->finish(0, \$statement);  # note that it's a scalar REFERENCE, not the scalar itself
+    }
+    $pm->wait_all_children;
+
+A second datastructure retrieval example demonstrates how children decide
+whether or not to send anything back, what to send and how the parent should
+process whatever is retrieved.
+
+    use Parallel::ForkManager 0.7.6;
+    use Data::Dumper;  # to display the data structures retrieved.
+    use strict;
+
+    my $pm = Parallel::ForkManager->new(20);  # using the system temp dir $L<File::Temp::tempdir()
+
+    # data structure retrieval and handling
+    my %retrieved_responses = ();  # for collecting responses
+    $pm -> run_on_finish (
+      sub {
+        my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+
+        # see what the child sent us, if anything
+        if (defined($data_structure_reference)) {  # test rather than assume child sent anything
+          my $reftype = ref($data_structure_reference);
+          print qq|ident "$ident" returned a "$reftype" reference.\n\n|;
+          if (1) {  # simple on/off switch to display the contents
+            print &Dumper($data_structure_reference) . qq|end of "$ident" sent structure\n\n|;
+          }
+
+          # we can also collect retrieved data structures for processing after all children have exited
+          $retrieved_responses{$ident} = $data_structure_reference;
+        } else {
+          print qq|ident "$ident" did not send anything.\n\n|;
+        }
+      }
+    );
+
+    # generate a list of instructions
+    my @instructions = (  # a unique identifier and what the child process should send
+      {'name' => '%ENV keys as a string', 'send' => 'keys'},
+      {'name' => 'Send Nothing'},  # not instructing the child to send anything back to the parent
+      {'name' => 'Childs %ENV', 'send' => 'all'},
+      {'name' => 'Child chooses randomly', 'send' => 'random'},
+      {'name' => 'Invalid send instructions', 'send' => 'Na Na Nana Na'},
+      {'name' => 'ENV values in an array', 'send' => 'values'},
+    );
+
+    INSTRUCTS:
+    foreach my $instruction (@instructions) {
+      $pm->start($instruction->{'name'}) and next INSTRUCTS;  # this time we are using an explicit, unique child process identifier
+
+      # last step in child processing
+      $pm->finish(0) unless $instruction->{'send'};  # no data structure is sent unless this child is told what to send.
+
+      if ($instruction->{'send'} eq 'keys') {
+        $pm->finish(0, \join(', ', keys %ENV));
+
+      } elsif ($instruction->{'send'} eq 'values') {
+        $pm->finish(0, [values %ENV]);  # kinda useless without knowing which keys they belong to...
+
+      } elsif ($instruction->{'send'} eq 'all') {
+        $pm->finish(0, \%ENV);  # remember, we are not "returning" anything, just copying the hash to disc
+
+      # demonstrate clearly that the child determines what type of reference to send
+      } elsif ($instruction->{'send'} eq 'random') {
+        my $string = q|I'm just a string.|;
+        my @array = qw(I am an array);
+        my %hash = (type => 'associative array', synonym => 'hash', cool => 'very :)');
+        my $return_choice = ('string', 'array', 'hash')[int(rand 3)];  # randomly choose return data type
+        $pm->finish(0, \$string) if ($return_choice eq 'string');
+        $pm->finish(0, \@array) if ($return_choice eq 'array');
+        $pm->finish(0, \%hash) if ($return_choice eq 'hash');
+
+      # as a responsible child, inform parent that their instruction was invalid
+      } else {
+        $pm->finish(0, \qq|Invalid instructions: "$instruction->{'send'}".|);  # ordinarily I wouldn't include invalid input in a response...
+      }
+    }
+    $pm->wait_all_children;  # blocks until all forked processes have exited
+
+    # post fork processing of returned data structures
+    for (sort keys %retrieved_responses) {
+      print qq|Post processing "$_"...\n|;
+    }
+
+# BUGS AND LIMITATIONS
+
+Do not use Parallel::ForkManager in an environment, where other child
+processes can affect the run of the main program, so using this module
+is not recommended in an environment where fork() / wait() is already used.
+
+If you want to use more than one copies of the Parallel::ForkManager, then
+you have to make sure that all children processes are terminated, before you
+use the second object in the main program.
+
+You are free to use a new copy of Parallel::ForkManager in the child
+processes, although I don't think it makes sense.
+
+# CREDITS
+
+    Michael Gang (bug report)
+    Noah Robin <sitz@onastick.net> (documentation tweaks)
+    Chuck Hirstius <chirstius@megapathdsl.net> (callback exit status, example)
+    Grant Hopwood <hopwoodg@valero.com> (win32 port)
+    Mark Southern <mark_southern@merck.com> (bugfix)
+    Ken Clarke <www.perlprogrammer.net>  (datastructure retrieval)
+
+# AUTHORS
+
+- dLux (Szabó, Balázs) <dlux@dlux.hu>
+- Yanick Champoux <yanick@cpan.org> [![endorse](http://api.coderwall.com/yanick/endorsecount.png)](http://coderwall.com/yanick)
+- Gabor Szabo <gabor@szabgab.com>
+
+# COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2000 by Balázs Szabó.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
diff --git a/Parallel-ForkManager-1.17/SIGNATURE b/Parallel-ForkManager-1.17/SIGNATURE
new file mode 100644 (file)
index 0000000..23f855a
--- /dev/null
@@ -0,0 +1,52 @@
+This file contains message digests of all files listed in MANIFEST,
+signed via the Module::Signature module, version 0.79.
+
+To verify the content in this distribution, first make sure you have
+Module::Signature installed, then type:
+
+    % cpansign -v
+
+It will check each file's integrity, as well as the signature's
+validity.  If "==> Signature verified OK! <==" is not displayed,
+the distribution may already have been compromised, and you should
+not run its Makefile.PL or Build.PL.
+
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+SHA1 fd95b68f03486ef0bc44ad34a47a130c661ed30e CONTRIBUTORS
+SHA1 10bdcac01393e5ff3a03d245444e7cda8064811c Changes
+SHA1 1fdb4343640b1dc9bf826eda0dd096ecbf52930d INSTALL
+SHA1 683ab41dd12f906c6c65287ca85ce58f84f27514 MANIFEST
+SHA1 f16787c18b2eb8168915e453ced37d2e6714d9da META.json
+SHA1 aae8180a3fad9c7feb904e748d96c63eeceba509 META.yml
+SHA1 473d501489198460965add67a59de09c83dcaf46 Makefile.PL
+SHA1 cfcf94230a45c69aa9dc9a0cdf265e5056e5d39b README.mkdn
+SHA1 15c889dc5dae788fc02fb6a7cc28cb9c49e4d82e cpanfile
+SHA1 81dd4c98191ca1e39e8faf44f4b139f26bec51c7 doap.xml
+SHA1 0bc4eff0fe3043f9fe2feb21b028780856e87203 examples/callback.pl
+SHA1 1b7dab748d481089c80d416d93b96115dc4486d4 examples/callback_data.pl
+SHA1 e14c174c581239b856e5b5c279716951a70f6eca examples/parallel_get.pl
+SHA1 a653898f3172f90461be45ceacd440f183bacc01 lib/Parallel/ForkManager.pm
+SHA1 562bfacd340b01259604e05492ef7f527d480958 t/00-compile.t
+SHA1 4439fa08acd3f8cfe4658640218be5fc4ed6c260 t/00-load.t
+SHA1 98b37452dda153ac3d85a6ae676ef248755d35ec t/00-report-prereqs.dd
+SHA1 504a672015f8761f5bad3863d844954c9e803c3f t/00-report-prereqs.t
+SHA1 4db3efffcfef330a6451166d6c7993f92bbba218 t/01-utf8-all.t
+SHA1 7ff8a7ee4a5960791a23a739a43b1628279548ef t/02-callback.t
+SHA1 ff8a6cea67626e7da6bf58c29c9b994d3991e4c9 t/03-callback-data.t
+SHA1 19208bbd9b74cd32cbc76dcbaf67c8ca4c17e866 t/basic-methods.t
+SHA1 6dce2e71e2969e784eb9a390a63b95ea05baef54 t/callback.txt
+SHA1 cef973989a30e506d69e7ab93ad174fcd10a1d99 t/callback_data.txt
+SHA1 e5f4aae96fc318e949d2367743e5d2ee12063246 t/waitpid-conflict.t
+SHA1 a91aaaf17a7a2878a8b031d2f686dc4bebefd2e1 t/waitpid-waitonechild.t
+SHA1 2fb16c9b79833c349b8429bcb047ffcbf64772a6 t/waitpid_blocking.t
+SHA1 80ab1faf5d8174920b60461bf8c11e2225861f42 xt/release/pause-permissions.t
+SHA1 d1fe7d94b3edc7847eb187d4ee41f66e19cf8907 xt/release/unused-vars.t
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iEYEARECAAYFAlZZvqQACgkQ34Hwf+GwC4wGMQCeNA0khEzl75EWPdR0hGyVgD42
+9I0AnA+fAUxua4DwI31mS6j9Sz0XJAHV
+=RGGU
+-----END PGP SIGNATURE-----
diff --git a/Parallel-ForkManager-1.17/blib/arch/.exists b/Parallel-ForkManager-1.17/blib/arch/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/blib/arch/auto/Parallel/ForkManager/.exists b/Parallel-ForkManager-1.17/blib/arch/auto/Parallel/ForkManager/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/blib/bin/.exists b/Parallel-ForkManager-1.17/blib/bin/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/blib/lib/Parallel/.exists b/Parallel-ForkManager-1.17/blib/lib/Parallel/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/blib/lib/Parallel/ForkManager.pm b/Parallel-ForkManager-1.17/blib/lib/Parallel/ForkManager.pm
new file mode 100644 (file)
index 0000000..01db006
--- /dev/null
@@ -0,0 +1,852 @@
+package Parallel::ForkManager;
+our $AUTHORITY = 'cpan:DLUX';
+# ABSTRACT:  A simple parallel processing fork manager
+$Parallel::ForkManager::VERSION = '1.17';
+use POSIX ":sys_wait_h";
+use Storable qw(store retrieve);
+use File::Spec;
+use File::Temp ();
+use File::Path ();
+use Carp;
+
+use strict;
+
+sub new {
+  my ($c,$processes,$tempdir)=@_;
+
+  my $h={
+    max_proc   => $processes,
+    processes  => {},
+    in_child   => 0,
+    parent_pid => $$,
+    auto_cleanup => ($tempdir ? 0 : 1),
+    waitpid_blocking_sleep => 1,
+  };
+
+
+  # determine temporary directory for storing data structures
+  # add it to Parallel::ForkManager object so children can use it
+  # We don't let it clean up so it won't do it in the child process
+  # but we have our own DESTROY to do that.
+  if (not defined($tempdir) or not length($tempdir)) {
+    $tempdir = File::Temp::tempdir(CLEANUP => 0);
+  }
+  die qq|Temporary directory "$tempdir" doesn't exist or is not a directory.| unless (-e $tempdir && -d _);  # ensure temp dir exists and is indeed a directory
+  $h->{tempdir} = $tempdir;
+
+  return bless($h,ref($c)||$c);
+};
+
+sub start {
+  my ($s,$identification)=@_;
+
+  die "Cannot start another process while you are in the child process"
+    if $s->{in_child};
+  while ($s->{max_proc} && ( keys %{ $s->{processes} } ) >= $s->{max_proc}) {
+    $s->on_wait;
+    $s->wait_one_child(defined $s->{on_wait_period} ? &WNOHANG : undef);
+  };
+  $s->wait_children;
+  if ($s->{max_proc}) {
+    my $pid=fork();
+    die "Cannot fork: $!" if !defined $pid;
+    if ($pid) {
+      $s->{processes}->{$pid}=$identification;
+      $s->on_start($pid,$identification);
+    } else {
+      $s->{in_child}=1 if !$pid;
+    }
+    return $pid;
+  } else {
+    $s->{processes}->{$$}=$identification;
+    $s->on_start($$,$identification);
+    return 0; # Simulating the child which returns 0
+  }
+}
+
+sub finish {
+  my ($s, $x, $r)=@_;
+
+  if ( $s->{in_child} ) {
+    if (defined($r)) {  # store the child's data structure
+      my $storable_tempfile = File::Spec->catfile($s->{tempdir}, 'Parallel-ForkManager-' . $s->{parent_pid} . '-' . $$ . '.txt');
+      my $stored = eval { return &store($r, $storable_tempfile); };
+
+      # handle Storables errors, IE logcarp or carp returning undef, or die (via logcroak or croak)
+      if (not $stored or $@) {
+        warn(qq|The storable module was unable to store the child's data structure to the temp file "$storable_tempfile":  | . join(', ', $@));
+      }
+    }
+    CORE::exit($x || 0);
+  }
+  if ($s->{max_proc} == 0) { # max_proc == 0
+    $s->on_finish($$, $x ,$s->{processes}->{$$}, 0, 0, $r);
+    delete $s->{processes}->{$$};
+  }
+  return 0;
+}
+
+sub wait_children {
+  my ($s)=@_;
+
+  return if !keys %{$s->{processes}};
+  my $kid;
+  do {
+    $kid = $s->wait_one_child(&WNOHANG);
+  } while defined $kid and ( $kid > 0 or $kid < -1 ); # AS 5.6/Win32 returns negative PIDs
+};
+
+*wait_childs=*wait_children; # compatibility
+*reap_finished_children=*wait_children; # behavioral synonym for clarity
+
+sub wait_one_child {
+  my ($s,$par)=@_;
+
+  my $kid;
+  while (1) {
+    $kid = $s->_waitpid(-1,$par||=0);
+
+    last unless defined $kid;
+
+    last if $kid == 0 || $kid == -1; # AS 5.6/Win32 returns negative PIDs
+    redo if !exists $s->{processes}->{$kid};
+    my $id = delete $s->{processes}->{$kid};
+
+    # retrieve child data structure, if any
+    my $retrieved = undef;
+    my $storable_tempfile = File::Spec->catfile($s->{tempdir}, 'Parallel-ForkManager-' . $$ . '-' . $kid . '.txt');
+    if (-e $storable_tempfile) {  # child has option of not storing anything, so we need to see if it did or not
+      $retrieved = eval { return &retrieve($storable_tempfile); };
+
+      # handle Storables errors
+      if (not $retrieved or $@) {
+        warn(qq|The storable module was unable to retrieve the child's data structure from the temporary file "$storable_tempfile":  | . join(', ', $@));
+      }
+
+      # clean up after ourselves
+      unlink $storable_tempfile;
+    }
+
+    $s->on_finish( $kid, $? >> 8 , $id, $? & 0x7f, $? & 0x80 ? 1 : 0, $retrieved);
+    last;
+  }
+  $kid;
+};
+
+sub wait_all_children {
+  my ($s)=@_;
+
+  while (keys %{ $s->{processes} }) {
+    $s->on_wait;
+    $s->wait_one_child(defined $s->{on_wait_period} ? &WNOHANG : undef);
+  };
+}
+
+*wait_all_childs=*wait_all_children; # compatibility;
+
+sub max_procs { $_[0]->{max_proc}; }
+
+sub is_child  { $_[0]->{in_child} }
+
+sub is_parent { !$_[0]->{in_child} }
+
+sub running_procs {
+    my $self = shift;
+
+    my @pids = keys %{ $self->{processes} };
+    return @pids;
+}
+
+sub wait_for_available_procs {
+    my( $self, $nbr ) = @_;
+    $nbr ||= 1;
+
+    croak "nbr processes '$nbr' higher than the max nbr of processes (@{[ $self->max_procs ]})"
+        if $nbr > $self->max_procs;
+
+    $self->wait_one_child until $self->max_procs - $self->running_procs >= $nbr;
+}
+
+sub run_on_finish {
+  my ($s,$code,$pid)=@_;
+
+  $s->{on_finish}->{$pid || 0}=$code;
+}
+
+sub on_finish {
+  my ($s,$pid,@par)=@_;
+
+  my $code=$s->{on_finish}->{$pid} || $s->{on_finish}->{0} or return 0;
+  $code->($pid,@par);
+};
+
+sub run_on_wait {
+  my ($s,$code, $period)=@_;
+
+  $s->{on_wait}=$code;
+  $s->{on_wait_period} = $period;
+}
+
+sub on_wait {
+  my ($s)=@_;
+
+  if(ref($s->{on_wait}) eq 'CODE') {
+    $s->{on_wait}->();
+    if (defined $s->{on_wait_period}) {
+        local $SIG{CHLD} = sub { } if ! defined $SIG{CHLD};
+        select undef, undef, undef, $s->{on_wait_period}
+    };
+  };
+};
+
+sub run_on_start {
+  my ($s,$code)=@_;
+
+  $s->{on_start}=$code;
+}
+
+sub on_start {
+  my ($s,@par)=@_;
+
+  $s->{on_start}->(@par) if ref($s->{on_start}) eq 'CODE';
+};
+
+sub set_max_procs {
+  my ($s, $mp)=@_;
+
+  $s->{max_proc} = $mp;
+}
+
+sub set_waitpid_blocking_sleep {
+    my( $self, $period ) = @_;
+    $self->{waitpid_blocking_sleep} = $period;
+}
+
+sub waitpid_blocking_sleep {
+    $_[0]->{waitpid_blocking_sleep};
+}
+
+sub _waitpid { # Call waitpid() in the standard Unix fashion.
+    my( $self, undef, $flag ) = @_;
+
+    return $flag ? $self->_waitpid_non_blocking : $self->_waitpid_blocking;
+}
+
+sub _waitpid_non_blocking {
+    my $self = shift;
+
+    for my $pid ( $self->running_procs ) {
+        my $p = waitpid $pid, &WNOHANG or next;
+
+        return $pid if $p != -1;
+
+        warn "child process '$pid' disappeared. A call to `waitpid` outside of Parallel::ForkManager might have reaped it.\n";
+        # it's gone. let's clean the process entry
+        delete $self->{processes}{$pid};
+    }
+
+    return;
+}
+
+sub _waitpid_blocking {
+    my $self = shift;
+
+    # pseudo-blocking
+    if( my $sleep_period = $self->{waitpid_blocking_sleep} ) {
+        while() {
+            my $pid = $self->_waitpid_non_blocking;
+
+            return $pid if defined $pid;
+
+            return unless $self->running_procs;
+
+            select undef, undef, undef, $sleep_period;
+        }
+    }
+
+    return waitpid -1, 0;
+}
+
+sub DESTROY {
+  my ($self) = @_;
+
+  if ($self->{auto_cleanup} && $self->{parent_pid} == $$ && -d $self->{tempdir}) {
+    File::Path::remove_tree($self->{tempdir});
+  }
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Parallel::ForkManager - A simple parallel processing fork manager
+
+=head1 VERSION
+
+version 1.17
+
+=head1 SYNOPSIS
+
+  use Parallel::ForkManager;
+
+  my $pm = Parallel::ForkManager->new($MAX_PROCESSES);
+
+  DATA_LOOP:
+  foreach my $data (@all_data) {
+    # Forks and returns the pid for the child:
+    my $pid = $pm->start and next DATA_LOOP;
+
+    ... do some work with $data in the child process ...
+
+    $pm->finish; # Terminates the child process
+  }
+
+=head1 DESCRIPTION
+
+This module is intended for use in operations that can be done in parallel
+where the number of processes to be forked off should be limited. Typical
+use is a downloader which will be retrieving hundreds/thousands of files.
+
+The code for a downloader would look something like this:
+
+  use LWP::Simple;
+  use Parallel::ForkManager;
+
+  ...
+
+  my @links=(
+    ["http://www.foo.bar/rulez.data","rulez_data.txt"],
+    ["http://new.host/more_data.doc","more_data.doc"],
+    ...
+  );
+
+  ...
+
+  # Max 30 processes for parallel download
+  my $pm = Parallel::ForkManager->new(30);
+
+  LINKS:
+  foreach my $linkarray (@links) {
+    $pm->start and next LINKS; # do the fork
+
+    my ($link, $fn) = @$linkarray;
+    warn "Cannot get $fn from $link"
+      if getstore($link, $fn) != RC_OK;
+
+    $pm->finish; # do the exit in the child process
+  }
+  $pm->wait_all_children;
+
+First you need to instantiate the ForkManager with the "new" constructor.
+You must specify the maximum number of processes to be created. If you
+specify 0, then NO fork will be done; this is good for debugging purposes.
+
+Next, use $pm->start to do the fork. $pm returns 0 for the child process,
+and child pid for the parent process (see also L<perlfunc(1p)/fork()>).
+The "and next" skips the internal loop in the parent process. NOTE:
+$pm->start dies if the fork fails.
+
+$pm->finish terminates the child process (assuming a fork was done in the
+"start").
+
+NOTE: You cannot use $pm->start if you are already in the child process.
+If you want to manage another set of subprocesses in the child process,
+you must instantiate another Parallel::ForkManager object!
+
+=head1 METHODS
+
+The comment letter indicates where the method should be run. P for parent,
+C for child.
+
+=over 5
+
+=item new $processes
+
+Instantiate a new Parallel::ForkManager object. You must specify the maximum
+number of children to fork off. If you specify 0 (zero), then no children
+will be forked. This is intended for debugging purposes.
+
+The optional second parameter, $tempdir, is only used if you want the
+children to send back a reference to some data (see RETRIEVING DATASTRUCTURES
+below). If not provided, it is set via a call to L<File::Temp>::tempdir().
+
+The new method will die if the temporary directory does not exist or it is not
+a directory.
+
+=item start [ $process_identifier ]
+
+This method does the fork. It returns the pid of the child process for
+the parent, and 0 for the child process. If the $processes parameter
+for the constructor is 0 then, assuming you're in the child process,
+$pm->start simply returns 0.
+
+An optional $process_identifier can be provided to this method... It is used by
+the "run_on_finish" callback (see CALLBACKS) for identifying the finished
+process.
+
+=item finish [ $exit_code [, $data_structure_reference] ]
+
+Closes the child process by exiting and accepts an optional exit code
+(default exit code is 0) which can be retrieved in the parent via callback.
+If the second optional parameter is provided, the child attempts to send
+it's contents back to the parent. If you use the program in debug mode
+($processes == 0), this method just calls the callback.
+
+If the $data_structure_reference is provided, then it is serialized and
+passed to the parent process. See RETRIEVING DATASTRUCTURES for more info.
+
+=item set_max_procs $processes
+
+Allows you to set a new maximum number of children to maintain.
+
+=item wait_all_children
+
+You can call this method to wait for all the processes which have been
+forked. This is a blocking wait.
+
+=item reap_finished_children
+
+This is a non-blocking call to reap children and execute callbacks independent
+of calls to "start" or "wait_all_children". Use this in scenarios where "start"
+is called infrequently but you would like the callbacks executed quickly.
+
+=item is_parent
+
+Returns C<true> if within the parent or C<false> if within the child.
+
+=item is_child
+
+Returns C<true> if within the child or C<false> if within the parent.
+
+=item max_procs 
+
+Returns the maximal number of processes the object will fork.
+
+=item running_procs
+
+Returns the pids of the forked processes currently monitored by the
+C<Parallel::ForkManager>. Note that children are still reported as running
+until the fork manager harvest them, via the next call to
+C<start> or C<wait_all_children>.
+
+    my @pids = $pm->running_procs;
+
+    my $nbr_children =- $pm->running_procs;
+
+=item wait_for_available_procs( $n )
+
+Wait until C<$n> available process slots are available.
+If C<$n> is not given, defaults to I<1>.
+
+=item waitpid_blocking_sleep 
+
+Returns the sleep period, in seconds, of the pseudo-blocking calls. The sleep
+period can be a fraction of second. 
+
+Returns C<0> if disabled. 
+
+Defaults to 1 second.
+
+See I<BLOCKING CALLS> for more details.
+
+=item set_waitpid_blocking_sleep $seconds
+
+Sets the the sleep period, in seconds, of the pseudo-blocking calls.
+Set to C<0> to disable.
+
+See I<BLOCKING CALLS> for more details.
+
+=back
+
+=head1 CALLBACKS
+
+You can define callbacks in the code, which are called on events like starting
+a process or upon finish. Declare these before the first call to start().
+
+The callbacks can be defined with the following methods:
+
+=over 4
+
+=item run_on_finish $code [, $pid ]
+
+You can define a subroutine which is called when a child is terminated. It is
+called in the parent process.
+
+The parameters of the $code are the following:
+
+  - pid of the process, which is terminated
+  - exit code of the program
+  - identification of the process (if provided in the "start" method)
+  - exit signal (0-127: signal name)
+  - core dump (1 if there was core dump at exit)
+  - datastructure reference or undef (see RETRIEVING DATASTRUCTURES)
+
+=item run_on_start $code
+
+You can define a subroutine which is called when a child is started. It called
+after the successful startup of a child in the parent process.
+
+The parameters of the $code are the following:
+
+  - pid of the process which has been started
+  - identification of the process (if provided in the "start" method)
+
+=item run_on_wait $code, [$period]
+
+You can define a subroutine which is called when the child process needs to wait
+for the startup. If $period is not defined, then one call is done per
+child. If $period is defined, then $code is called periodically and the
+module waits for $period seconds between the two calls. Note, $period can be
+fractional number also. The exact "$period seconds" is not guaranteed,
+signals can shorten and the process scheduler can make it longer (on busy
+systems).
+
+The $code called in the "start" and the "wait_all_children" method also.
+
+No parameters are passed to the $code on the call.
+
+=back
+
+=head1 BLOCKING CALLS
+
+When it comes to waiting for child processes to terminate, C<Parallel::ForkManager> is between 
+a fork and a hard place (if you excuse the terrible pun). The underlying Perl C<waitpid> function
+that the module relies on can block until either one specific or any child process 
+terminate, but not for a process part of a given group.
+
+This means that the module can do one of two things when it waits for 
+one of its child processes to terminate:
+
+=over
+
+=item Only wait for its own child processes
+
+This is done via a loop using a C<waitpid> non-blocking call and a sleep statement.
+The code does something along the lines of
+
+    while(1) {
+        if ( any of the P::FM child process terminated ) {
+            return its pid
+        }
+
+        sleep $sleep_period
+    }
+
+This is the default behavior that the module will use.
+This is not the most efficient way to wait for child processes, but it's
+the safest way to ensure that C<Parallel::ForkManager> won't interfere with 
+any other part of the codebase. 
+
+The sleep period is set via the method C<set_waitpid_blocking_sleep>.
+
+=item Block until any process terminate
+
+Alternatively, C<Parallel::ForkManager> can call C<waitpid> such that it will
+block until any child process terminate. If the child process was not one of
+the monitored subprocesses, the wait will resume. This is more efficient, but mean
+that C<P::FM> can captures (and discards) the termination notification that a different
+part of the code might be waiting for. 
+
+If this is a race condition
+that doesn't apply to your codebase, you can set the 
+I<waitpid_blocking_sleep> period to C<0>, which will enable C<waitpid> call blocking.
+
+    my $pm = Parallel::ForkManager->new( 4 );
+
+    $pm->set_waitpid_blocking_sleep(0);  # true blocking calls enabled
+
+    for ( 1..100 ) {
+        $pm->start and next;
+
+        ...; # do work
+
+        $pm->finish;
+    }
+
+=back
+
+=head1 RETRIEVING DATASTRUCTURES from child processes
+
+The ability for the parent to retrieve data structures is new as of version
+0.7.6.
+
+Each child process may optionally send 1 data structure back to the parent.
+By data structure, we mean a reference to a string, hash or array. The
+contents of the data structure are written out to temporary files on disc
+using the L<Storable> modules' store() method. The reference is then
+retrieved from within the code you send to the run_on_finish callback.
+
+The data structure can be any scalar perl data structure which makes sense:
+string, numeric value or a reference to an array, hash or object.
+
+There are 2 steps involved in retrieving data structures:
+
+1) A reference to the data structure the child wishes to send back to the
+parent is provided as the second argument to the finish() call. It is up
+to the child to decide whether or not to send anything back to the parent.
+
+2) The data structure reference is retrieved using the callback provided in
+the run_on_finish() method.
+
+Keep in mind that data structure retrieval is not the same as returning a
+data structure from a method call. That is not what actually occurs. The
+data structure referenced in a given child process is serialized and
+written out to a file by L<Storable>. The file is subsequently read back
+into memory and a new data structure belonging to the parent process is
+created. Please consider the performance penality it can imply, so try to
+keep the returned structure small.
+
+=head1 EXAMPLES
+
+=head2 Parallel get
+
+This small example can be used to get URLs in parallel.
+
+  use Parallel::ForkManager;
+  use LWP::Simple;
+
+  my $pm = Parallel::ForkManager->new(10);
+
+  LINKS:
+  for my $link (@ARGV) {
+    $pm->start and next LINKS;
+    my ($fn) = $link =~ /^.*\/(.*?)$/;
+    if (!$fn) {
+      warn "Cannot determine filename from $fn\n";
+    } else {
+      $0 .= " " . $fn;
+      print "Getting $fn from $link\n";
+      my $rc = getstore($link, $fn);
+      print "$link downloaded. response code: $rc\n";
+    };
+    $pm->finish;
+  };
+
+=head2 Callbacks
+
+Example of a program using callbacks to get child exit codes:
+
+  use strict;
+  use Parallel::ForkManager;
+
+  my $max_procs = 5;
+  my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara );
+  # hash to resolve PID's back to child specific information
+
+  my $pm = Parallel::ForkManager->new($max_procs);
+
+  # Setup a callback for when a child finishes up so we can
+  # get it's exit code
+  $pm->run_on_finish( sub {
+      my ($pid, $exit_code, $ident) = @_;
+      print "** $ident just got out of the pool ".
+        "with PID $pid and exit code: $exit_code\n";
+  });
+
+  $pm->run_on_start( sub {
+      my ($pid, $ident)=@_;
+      print "** $ident started, pid: $pid\n";
+  });
+
+  $pm->run_on_wait( sub {
+      print "** Have to wait for one children ...\n"
+    },
+    0.5
+  );
+
+  NAMES:
+  foreach my $child ( 0 .. $#names ) {
+    my $pid = $pm->start($names[$child]) and next NAMES;
+
+    # This code is the child process
+    print "This is $names[$child], Child number $child\n";
+    sleep ( 2 * $child );
+    print "$names[$child], Child $child is about to get out...\n";
+    sleep 1;
+    $pm->finish($child); # pass an exit code to finish
+  }
+
+  print "Waiting for Children...\n";
+  $pm->wait_all_children;
+  print "Everybody is out of the pool!\n";
+
+=head2 Data structure retrieval
+
+In this simple example, each child sends back a string reference.
+
+  use Parallel::ForkManager 0.7.6;
+  use strict;
+
+  my $pm = Parallel::ForkManager->new(2, '/server/path/to/temp/dir/');
+
+  # data structure retrieval and handling
+  $pm -> run_on_finish ( # called BEFORE the first call to start()
+    sub {
+      my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+
+      # retrieve data structure from child
+      if (defined($data_structure_reference)) {  # children are not forced to send anything
+        my $string = ${$data_structure_reference};  # child passed a string reference
+        print "$string\n";
+      }
+      else {  # problems occuring during storage or retrieval will throw a warning
+        print qq|No message received from child process $pid!\n|;
+      }
+    }
+  );
+
+  # prep random statement components
+  my @foods = ('chocolate', 'ice cream', 'peanut butter', 'pickles', 'pizza', 'bacon', 'pancakes', 'spaghetti', 'cookies');
+  my @preferences = ('loves', q|can't stand|, 'always wants more', 'will walk 100 miles for', 'only eats', 'would starve rather than eat');
+
+  # run the parallel processes
+  PERSONS:
+  foreach my $person (qw(Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry)) {
+    $pm->start() and next PERSONS;
+
+    # generate a random statement about food preferences
+    my $statement = $person . ' ' . $preferences[int(rand @preferences)] . ' ' . $foods[int(rand @foods)];
+
+    # send it back to the parent process
+    $pm->finish(0, \$statement);  # note that it's a scalar REFERENCE, not the scalar itself
+  }
+  $pm->wait_all_children;
+
+A second datastructure retrieval example demonstrates how children decide
+whether or not to send anything back, what to send and how the parent should
+process whatever is retrieved.
+
+=for example begin
+
+  use Parallel::ForkManager 0.7.6;
+  use Data::Dumper;  # to display the data structures retrieved.
+  use strict;
+
+  my $pm = Parallel::ForkManager->new(20);  # using the system temp dir $L<File::Temp::tempdir()
+
+  # data structure retrieval and handling
+  my %retrieved_responses = ();  # for collecting responses
+  $pm -> run_on_finish (
+    sub {
+      my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+
+      # see what the child sent us, if anything
+      if (defined($data_structure_reference)) {  # test rather than assume child sent anything
+        my $reftype = ref($data_structure_reference);
+        print qq|ident "$ident" returned a "$reftype" reference.\n\n|;
+        if (1) {  # simple on/off switch to display the contents
+          print &Dumper($data_structure_reference) . qq|end of "$ident" sent structure\n\n|;
+        }
+
+        # we can also collect retrieved data structures for processing after all children have exited
+        $retrieved_responses{$ident} = $data_structure_reference;
+      } else {
+        print qq|ident "$ident" did not send anything.\n\n|;
+      }
+    }
+  );
+
+  # generate a list of instructions
+  my @instructions = (  # a unique identifier and what the child process should send
+    {'name' => '%ENV keys as a string', 'send' => 'keys'},
+    {'name' => 'Send Nothing'},  # not instructing the child to send anything back to the parent
+    {'name' => 'Childs %ENV', 'send' => 'all'},
+    {'name' => 'Child chooses randomly', 'send' => 'random'},
+    {'name' => 'Invalid send instructions', 'send' => 'Na Na Nana Na'},
+    {'name' => 'ENV values in an array', 'send' => 'values'},
+  );
+
+  INSTRUCTS:
+  foreach my $instruction (@instructions) {
+    $pm->start($instruction->{'name'}) and next INSTRUCTS;  # this time we are using an explicit, unique child process identifier
+
+    # last step in child processing
+    $pm->finish(0) unless $instruction->{'send'};  # no data structure is sent unless this child is told what to send.
+
+    if ($instruction->{'send'} eq 'keys') {
+      $pm->finish(0, \join(', ', keys %ENV));
+
+    } elsif ($instruction->{'send'} eq 'values') {
+      $pm->finish(0, [values %ENV]);  # kinda useless without knowing which keys they belong to...
+
+    } elsif ($instruction->{'send'} eq 'all') {
+      $pm->finish(0, \%ENV);  # remember, we are not "returning" anything, just copying the hash to disc
+
+    # demonstrate clearly that the child determines what type of reference to send
+    } elsif ($instruction->{'send'} eq 'random') {
+      my $string = q|I'm just a string.|;
+      my @array = qw(I am an array);
+      my %hash = (type => 'associative array', synonym => 'hash', cool => 'very :)');
+      my $return_choice = ('string', 'array', 'hash')[int(rand 3)];  # randomly choose return data type
+      $pm->finish(0, \$string) if ($return_choice eq 'string');
+      $pm->finish(0, \@array) if ($return_choice eq 'array');
+      $pm->finish(0, \%hash) if ($return_choice eq 'hash');
+
+    # as a responsible child, inform parent that their instruction was invalid
+    } else {
+      $pm->finish(0, \qq|Invalid instructions: "$instruction->{'send'}".|);  # ordinarily I wouldn't include invalid input in a response...
+    }
+  }
+  $pm->wait_all_children;  # blocks until all forked processes have exited
+
+  # post fork processing of returned data structures
+  for (sort keys %retrieved_responses) {
+    print qq|Post processing "$_"...\n|;
+  }
+
+=for example end
+
+=head1 BUGS AND LIMITATIONS
+
+Do not use Parallel::ForkManager in an environment, where other child
+processes can affect the run of the main program, so using this module
+is not recommended in an environment where fork() / wait() is already used.
+
+If you want to use more than one copies of the Parallel::ForkManager, then
+you have to make sure that all children processes are terminated, before you
+use the second object in the main program.
+
+You are free to use a new copy of Parallel::ForkManager in the child
+processes, although I don't think it makes sense.
+
+=head1 CREDITS
+
+  Michael Gang (bug report)
+  Noah Robin <sitz@onastick.net> (documentation tweaks)
+  Chuck Hirstius <chirstius@megapathdsl.net> (callback exit status, example)
+  Grant Hopwood <hopwoodg@valero.com> (win32 port)
+  Mark Southern <mark_southern@merck.com> (bugfix)
+  Ken Clarke <www.perlprogrammer.net>  (datastructure retrieval)
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+dLux (Szabó, Balázs) <dlux@dlux.hu>
+
+=item *
+
+Yanick Champoux <yanick@cpan.org>
+
+=item *
+
+Gabor Szabo <gabor@szabgab.com>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2000 by Balázs Szabó.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
diff --git a/Parallel-ForkManager-1.17/blib/lib/auto/Parallel/ForkManager/.exists b/Parallel-ForkManager-1.17/blib/lib/auto/Parallel/ForkManager/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/blib/man1/.exists b/Parallel-ForkManager-1.17/blib/man1/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/blib/man3/.exists b/Parallel-ForkManager-1.17/blib/man3/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/blib/man3/Parallel::ForkManager.3pm b/Parallel-ForkManager-1.17/blib/man3/Parallel::ForkManager.3pm
new file mode 100644 (file)
index 0000000..d74d293
--- /dev/null
@@ -0,0 +1,680 @@
+.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
+.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+.    ds C`
+.    ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{
+.    if \nF \{
+.        de IX
+.        tm Index:\\$1\t\\n%\t"\\$2"
+..
+.        if !\nF==2 \{
+.            nr % 0
+.            nr F 2
+.        \}
+.    \}
+.\}
+.rr rF
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "Parallel::ForkManager 3pm"
+.TH Parallel::ForkManager 3pm "2015-11-28" "perl v5.18.2" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+Parallel::ForkManager \- A simple parallel processing fork manager
+.SH "VERSION"
+.IX Header "VERSION"
+version 1.17
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 1
+\&  use Parallel::ForkManager;
+\&
+\&  my $pm = Parallel::ForkManager\->new($MAX_PROCESSES);
+\&
+\&  DATA_LOOP:
+\&  foreach my $data (@all_data) {
+\&    # Forks and returns the pid for the child:
+\&    my $pid = $pm\->start and next DATA_LOOP;
+\&
+\&    ... do some work with $data in the child process ...
+\&
+\&    $pm\->finish; # Terminates the child process
+\&  }
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This module is intended for use in operations that can be done in parallel
+where the number of processes to be forked off should be limited. Typical
+use is a downloader which will be retrieving hundreds/thousands of files.
+.PP
+The code for a downloader would look something like this:
+.PP
+.Vb 2
+\&  use LWP::Simple;
+\&  use Parallel::ForkManager;
+\&
+\&  ...
+\&
+\&  my @links=(
+\&    ["http://www.foo.bar/rulez.data","rulez_data.txt"],
+\&    ["http://new.host/more_data.doc","more_data.doc"],
+\&    ...
+\&  );
+\&
+\&  ...
+\&
+\&  # Max 30 processes for parallel download
+\&  my $pm = Parallel::ForkManager\->new(30);
+\&
+\&  LINKS:
+\&  foreach my $linkarray (@links) {
+\&    $pm\->start and next LINKS; # do the fork
+\&
+\&    my ($link, $fn) = @$linkarray;
+\&    warn "Cannot get $fn from $link"
+\&      if getstore($link, $fn) != RC_OK;
+\&
+\&    $pm\->finish; # do the exit in the child process
+\&  }
+\&  $pm\->wait_all_children;
+.Ve
+.PP
+First you need to instantiate the ForkManager with the \*(L"new\*(R" constructor.
+You must specify the maximum number of processes to be created. If you
+specify 0, then \s-1NO\s0 fork will be done; this is good for debugging purposes.
+.PP
+Next, use \f(CW$pm\fR\->start to do the fork. \f(CW$pm\fR returns 0 for the child process,
+and child pid for the parent process (see also \*(L"\fIfork()\fR\*(R" in \fIperlfunc\fR\|(1p)).
+The \*(L"and next\*(R" skips the internal loop in the parent process. \s-1NOTE:\s0
+\&\f(CW$pm\fR\->start dies if the fork fails.
+.PP
+\&\f(CW$pm\fR\->finish terminates the child process (assuming a fork was done in the
+\&\*(L"start\*(R").
+.PP
+\&\s-1NOTE:\s0 You cannot use \f(CW$pm\fR\->start if you are already in the child process.
+If you want to manage another set of subprocesses in the child process,
+you must instantiate another Parallel::ForkManager object!
+.SH "METHODS"
+.IX Header "METHODS"
+The comment letter indicates where the method should be run. P for parent,
+C for child.
+.ie n .IP "new $processes" 5
+.el .IP "new \f(CW$processes\fR" 5
+.IX Item "new $processes"
+Instantiate a new Parallel::ForkManager object. You must specify the maximum
+number of children to fork off. If you specify 0 (zero), then no children
+will be forked. This is intended for debugging purposes.
+.Sp
+The optional second parameter, \f(CW$tempdir\fR, is only used if you want the
+children to send back a reference to some data (see \s-1RETRIEVING DATASTRUCTURES\s0
+below). If not provided, it is set via a call to File::Temp::\fItempdir()\fR.
+.Sp
+The new method will die if the temporary directory does not exist or it is not
+a directory.
+.ie n .IP "start [ $process_identifier ]" 5
+.el .IP "start [ \f(CW$process_identifier\fR ]" 5
+.IX Item "start [ $process_identifier ]"
+This method does the fork. It returns the pid of the child process for
+the parent, and 0 for the child process. If the \f(CW$processes\fR parameter
+for the constructor is 0 then, assuming you're in the child process,
+\&\f(CW$pm\fR\->start simply returns 0.
+.Sp
+An optional \f(CW$process_identifier\fR can be provided to this method... It is used by
+the \*(L"run_on_finish\*(R" callback (see \s-1CALLBACKS\s0) for identifying the finished
+process.
+.ie n .IP "finish [ $exit_code [, $data_structure_reference] ]" 5
+.el .IP "finish [ \f(CW$exit_code\fR [, \f(CW$data_structure_reference\fR] ]" 5
+.IX Item "finish [ $exit_code [, $data_structure_reference] ]"
+Closes the child process by exiting and accepts an optional exit code
+(default exit code is 0) which can be retrieved in the parent via callback.
+If the second optional parameter is provided, the child attempts to send
+it's contents back to the parent. If you use the program in debug mode
+($processes == 0), this method just calls the callback.
+.Sp
+If the \f(CW$data_structure_reference\fR is provided, then it is serialized and
+passed to the parent process. See \s-1RETRIEVING DATASTRUCTURES\s0 for more info.
+.ie n .IP "set_max_procs $processes" 5
+.el .IP "set_max_procs \f(CW$processes\fR" 5
+.IX Item "set_max_procs $processes"
+Allows you to set a new maximum number of children to maintain.
+.IP "wait_all_children" 5
+.IX Item "wait_all_children"
+You can call this method to wait for all the processes which have been
+forked. This is a blocking wait.
+.IP "reap_finished_children" 5
+.IX Item "reap_finished_children"
+This is a non-blocking call to reap children and execute callbacks independent
+of calls to \*(L"start\*(R" or \*(L"wait_all_children\*(R". Use this in scenarios where \*(L"start\*(R"
+is called infrequently but you would like the callbacks executed quickly.
+.IP "is_parent" 5
+.IX Item "is_parent"
+Returns \f(CW\*(C`true\*(C'\fR if within the parent or \f(CW\*(C`false\*(C'\fR if within the child.
+.IP "is_child" 5
+.IX Item "is_child"
+Returns \f(CW\*(C`true\*(C'\fR if within the child or \f(CW\*(C`false\*(C'\fR if within the parent.
+.IP "max_procs" 5
+.IX Item "max_procs"
+Returns the maximal number of processes the object will fork.
+.IP "running_procs" 5
+.IX Item "running_procs"
+Returns the pids of the forked processes currently monitored by the
+\&\f(CW\*(C`Parallel::ForkManager\*(C'\fR. Note that children are still reported as running
+until the fork manager harvest them, via the next call to
+\&\f(CW\*(C`start\*(C'\fR or \f(CW\*(C`wait_all_children\*(C'\fR.
+.Sp
+.Vb 1
+\&    my @pids = $pm\->running_procs;
+\&
+\&    my $nbr_children =\- $pm\->running_procs;
+.Ve
+.ie n .IP "wait_for_available_procs( $n )" 5
+.el .IP "wait_for_available_procs( \f(CW$n\fR )" 5
+.IX Item "wait_for_available_procs( $n )"
+Wait until \f(CW$n\fR available process slots are available.
+If \f(CW$n\fR is not given, defaults to \fI1\fR.
+.IP "waitpid_blocking_sleep" 5
+.IX Item "waitpid_blocking_sleep"
+Returns the sleep period, in seconds, of the pseudo-blocking calls. The sleep
+period can be a fraction of second.
+.Sp
+Returns \f(CW0\fR if disabled.
+.Sp
+Defaults to 1 second.
+.Sp
+See \fI\s-1BLOCKING CALLS\s0\fR for more details.
+.ie n .IP "set_waitpid_blocking_sleep $seconds" 5
+.el .IP "set_waitpid_blocking_sleep \f(CW$seconds\fR" 5
+.IX Item "set_waitpid_blocking_sleep $seconds"
+Sets the the sleep period, in seconds, of the pseudo-blocking calls.
+Set to \f(CW0\fR to disable.
+.Sp
+See \fI\s-1BLOCKING CALLS\s0\fR for more details.
+.SH "CALLBACKS"
+.IX Header "CALLBACKS"
+You can define callbacks in the code, which are called on events like starting
+a process or upon finish. Declare these before the first call to \fIstart()\fR.
+.PP
+The callbacks can be defined with the following methods:
+.ie n .IP "run_on_finish $code [, $pid ]" 4
+.el .IP "run_on_finish \f(CW$code\fR [, \f(CW$pid\fR ]" 4
+.IX Item "run_on_finish $code [, $pid ]"
+You can define a subroutine which is called when a child is terminated. It is
+called in the parent process.
+.Sp
+The parameters of the \f(CW$code\fR are the following:
+.Sp
+.Vb 6
+\&  \- pid of the process, which is terminated
+\&  \- exit code of the program
+\&  \- identification of the process (if provided in the "start" method)
+\&  \- exit signal (0\-127: signal name)
+\&  \- core dump (1 if there was core dump at exit)
+\&  \- datastructure reference or undef (see RETRIEVING DATASTRUCTURES)
+.Ve
+.ie n .IP "run_on_start $code" 4
+.el .IP "run_on_start \f(CW$code\fR" 4
+.IX Item "run_on_start $code"
+You can define a subroutine which is called when a child is started. It called
+after the successful startup of a child in the parent process.
+.Sp
+The parameters of the \f(CW$code\fR are the following:
+.Sp
+.Vb 2
+\&  \- pid of the process which has been started
+\&  \- identification of the process (if provided in the "start" method)
+.Ve
+.ie n .IP "run_on_wait $code, [$period]" 4
+.el .IP "run_on_wait \f(CW$code\fR, [$period]" 4
+.IX Item "run_on_wait $code, [$period]"
+You can define a subroutine which is called when the child process needs to wait
+for the startup. If \f(CW$period\fR is not defined, then one call is done per
+child. If \f(CW$period\fR is defined, then \f(CW$code\fR is called periodically and the
+module waits for \f(CW$period\fR seconds between the two calls. Note, \f(CW$period\fR can be
+fractional number also. The exact \*(L"$period seconds\*(R" is not guaranteed,
+signals can shorten and the process scheduler can make it longer (on busy
+systems).
+.Sp
+The \f(CW$code\fR called in the \*(L"start\*(R" and the \*(L"wait_all_children\*(R" method also.
+.Sp
+No parameters are passed to the \f(CW$code\fR on the call.
+.SH "BLOCKING CALLS"
+.IX Header "BLOCKING CALLS"
+When it comes to waiting for child processes to terminate, \f(CW\*(C`Parallel::ForkManager\*(C'\fR is between 
+a fork and a hard place (if you excuse the terrible pun). The underlying Perl \f(CW\*(C`waitpid\*(C'\fR function
+that the module relies on can block until either one specific or any child process 
+terminate, but not for a process part of a given group.
+.PP
+This means that the module can do one of two things when it waits for 
+one of its child processes to terminate:
+.IP "Only wait for its own child processes" 4
+.IX Item "Only wait for its own child processes"
+This is done via a loop using a \f(CW\*(C`waitpid\*(C'\fR non-blocking call and a sleep statement.
+The code does something along the lines of
+.Sp
+.Vb 4
+\&    while(1) {
+\&        if ( any of the P::FM child process terminated ) {
+\&            return its pid
+\&        }
+\&
+\&        sleep $sleep_period
+\&    }
+.Ve
+.Sp
+This is the default behavior that the module will use.
+This is not the most efficient way to wait for child processes, but it's
+the safest way to ensure that \f(CW\*(C`Parallel::ForkManager\*(C'\fR won't interfere with 
+any other part of the codebase.
+.Sp
+The sleep period is set via the method \f(CW\*(C`set_waitpid_blocking_sleep\*(C'\fR.
+.IP "Block until any process terminate" 4
+.IX Item "Block until any process terminate"
+Alternatively, \f(CW\*(C`Parallel::ForkManager\*(C'\fR can call \f(CW\*(C`waitpid\*(C'\fR such that it will
+block until any child process terminate. If the child process was not one of
+the monitored subprocesses, the wait will resume. This is more efficient, but mean
+that \f(CW\*(C`P::FM\*(C'\fR can captures (and discards) the termination notification that a different
+part of the code might be waiting for.
+.Sp
+If this is a race condition
+that doesn't apply to your codebase, you can set the 
+\&\fIwaitpid_blocking_sleep\fR period to \f(CW0\fR, which will enable \f(CW\*(C`waitpid\*(C'\fR call blocking.
+.Sp
+.Vb 1
+\&    my $pm = Parallel::ForkManager\->new( 4 );
+\&
+\&    $pm\->set_waitpid_blocking_sleep(0);  # true blocking calls enabled
+\&
+\&    for ( 1..100 ) {
+\&        $pm\->start and next;
+\&
+\&        ...; # do work
+\&
+\&        $pm\->finish;
+\&    }
+.Ve
+.SH "RETRIEVING DATASTRUCTURES from child processes"
+.IX Header "RETRIEVING DATASTRUCTURES from child processes"
+The ability for the parent to retrieve data structures is new as of version
+0.7.6.
+.PP
+Each child process may optionally send 1 data structure back to the parent.
+By data structure, we mean a reference to a string, hash or array. The
+contents of the data structure are written out to temporary files on disc
+using the Storable modules' \fIstore()\fR method. The reference is then
+retrieved from within the code you send to the run_on_finish callback.
+.PP
+The data structure can be any scalar perl data structure which makes sense:
+string, numeric value or a reference to an array, hash or object.
+.PP
+There are 2 steps involved in retrieving data structures:
+.PP
+1) A reference to the data structure the child wishes to send back to the
+parent is provided as the second argument to the \fIfinish()\fR call. It is up
+to the child to decide whether or not to send anything back to the parent.
+.PP
+2) The data structure reference is retrieved using the callback provided in
+the \fIrun_on_finish()\fR method.
+.PP
+Keep in mind that data structure retrieval is not the same as returning a
+data structure from a method call. That is not what actually occurs. The
+data structure referenced in a given child process is serialized and
+written out to a file by Storable. The file is subsequently read back
+into memory and a new data structure belonging to the parent process is
+created. Please consider the performance penality it can imply, so try to
+keep the returned structure small.
+.SH "EXAMPLES"
+.IX Header "EXAMPLES"
+.SS "Parallel get"
+.IX Subsection "Parallel get"
+This small example can be used to get URLs in parallel.
+.PP
+.Vb 2
+\&  use Parallel::ForkManager;
+\&  use LWP::Simple;
+\&
+\&  my $pm = Parallel::ForkManager\->new(10);
+\&
+\&  LINKS:
+\&  for my $link (@ARGV) {
+\&    $pm\->start and next LINKS;
+\&    my ($fn) = $link =~ /^.*\e/(.*?)$/;
+\&    if (!$fn) {
+\&      warn "Cannot determine filename from $fn\en";
+\&    } else {
+\&      $0 .= " " . $fn;
+\&      print "Getting $fn from $link\en";
+\&      my $rc = getstore($link, $fn);
+\&      print "$link downloaded. response code: $rc\en";
+\&    };
+\&    $pm\->finish;
+\&  };
+.Ve
+.SS "Callbacks"
+.IX Subsection "Callbacks"
+Example of a program using callbacks to get child exit codes:
+.PP
+.Vb 2
+\&  use strict;
+\&  use Parallel::ForkManager;
+\&
+\&  my $max_procs = 5;
+\&  my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara );
+\&  # hash to resolve PID\*(Aqs back to child specific information
+\&
+\&  my $pm = Parallel::ForkManager\->new($max_procs);
+\&
+\&  # Setup a callback for when a child finishes up so we can
+\&  # get it\*(Aqs exit code
+\&  $pm\->run_on_finish( sub {
+\&      my ($pid, $exit_code, $ident) = @_;
+\&      print "** $ident just got out of the pool ".
+\&        "with PID $pid and exit code: $exit_code\en";
+\&  });
+\&
+\&  $pm\->run_on_start( sub {
+\&      my ($pid, $ident)=@_;
+\&      print "** $ident started, pid: $pid\en";
+\&  });
+\&
+\&  $pm\->run_on_wait( sub {
+\&      print "** Have to wait for one children ...\en"
+\&    },
+\&    0.5
+\&  );
+\&
+\&  NAMES:
+\&  foreach my $child ( 0 .. $#names ) {
+\&    my $pid = $pm\->start($names[$child]) and next NAMES;
+\&
+\&    # This code is the child process
+\&    print "This is $names[$child], Child number $child\en";
+\&    sleep ( 2 * $child );
+\&    print "$names[$child], Child $child is about to get out...\en";
+\&    sleep 1;
+\&    $pm\->finish($child); # pass an exit code to finish
+\&  }
+\&
+\&  print "Waiting for Children...\en";
+\&  $pm\->wait_all_children;
+\&  print "Everybody is out of the pool!\en";
+.Ve
+.SS "Data structure retrieval"
+.IX Subsection "Data structure retrieval"
+In this simple example, each child sends back a string reference.
+.PP
+.Vb 2
+\&  use Parallel::ForkManager 0.7.6;
+\&  use strict;
+\&
+\&  my $pm = Parallel::ForkManager\->new(2, \*(Aq/server/path/to/temp/dir/\*(Aq);
+\&
+\&  # data structure retrieval and handling
+\&  $pm \-> run_on_finish ( # called BEFORE the first call to start()
+\&    sub {
+\&      my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+\&
+\&      # retrieve data structure from child
+\&      if (defined($data_structure_reference)) {  # children are not forced to send anything
+\&        my $string = ${$data_structure_reference};  # child passed a string reference
+\&        print "$string\en";
+\&      }
+\&      else {  # problems occuring during storage or retrieval will throw a warning
+\&        print qq|No message received from child process $pid!\en|;
+\&      }
+\&    }
+\&  );
+\&
+\&  # prep random statement components
+\&  my @foods = (\*(Aqchocolate\*(Aq, \*(Aqice cream\*(Aq, \*(Aqpeanut butter\*(Aq, \*(Aqpickles\*(Aq, \*(Aqpizza\*(Aq, \*(Aqbacon\*(Aq, \*(Aqpancakes\*(Aq, \*(Aqspaghetti\*(Aq, \*(Aqcookies\*(Aq);
+\&  my @preferences = (\*(Aqloves\*(Aq, q|can\*(Aqt stand|, \*(Aqalways wants more\*(Aq, \*(Aqwill walk 100 miles for\*(Aq, \*(Aqonly eats\*(Aq, \*(Aqwould starve rather than eat\*(Aq);
+\&
+\&  # run the parallel processes
+\&  PERSONS:
+\&  foreach my $person (qw(Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry)) {
+\&    $pm\->start() and next PERSONS;
+\&
+\&    # generate a random statement about food preferences
+\&    my $statement = $person . \*(Aq \*(Aq . $preferences[int(rand @preferences)] . \*(Aq \*(Aq . $foods[int(rand @foods)];
+\&
+\&    # send it back to the parent process
+\&    $pm\->finish(0, \e$statement);  # note that it\*(Aqs a scalar REFERENCE, not the scalar itself
+\&  }
+\&  $pm\->wait_all_children;
+.Ve
+.PP
+A second datastructure retrieval example demonstrates how children decide
+whether or not to send anything back, what to send and how the parent should
+process whatever is retrieved.
+.PP
+.Vb 3
+\&  use Parallel::ForkManager 0.7.6;
+\&  use Data::Dumper;  # to display the data structures retrieved.
+\&  use strict;
+\&
+\&  my $pm = Parallel::ForkManager\->new(20);  # using the system temp dir $L<File::Temp::tempdir()
+\&
+\&  # data structure retrieval and handling
+\&  my %retrieved_responses = ();  # for collecting responses
+\&  $pm \-> run_on_finish (
+\&    sub {
+\&      my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+\&
+\&      # see what the child sent us, if anything
+\&      if (defined($data_structure_reference)) {  # test rather than assume child sent anything
+\&        my $reftype = ref($data_structure_reference);
+\&        print qq|ident "$ident" returned a "$reftype" reference.\en\en|;
+\&        if (1) {  # simple on/off switch to display the contents
+\&          print &Dumper($data_structure_reference) . qq|end of "$ident" sent structure\en\en|;
+\&        }
+\&
+\&        # we can also collect retrieved data structures for processing after all children have exited
+\&        $retrieved_responses{$ident} = $data_structure_reference;
+\&      } else {
+\&        print qq|ident "$ident" did not send anything.\en\en|;
+\&      }
+\&    }
+\&  );
+\&
+\&  # generate a list of instructions
+\&  my @instructions = (  # a unique identifier and what the child process should send
+\&    {\*(Aqname\*(Aq => \*(Aq%ENV keys as a string\*(Aq, \*(Aqsend\*(Aq => \*(Aqkeys\*(Aq},
+\&    {\*(Aqname\*(Aq => \*(AqSend Nothing\*(Aq},  # not instructing the child to send anything back to the parent
+\&    {\*(Aqname\*(Aq => \*(AqChilds %ENV\*(Aq, \*(Aqsend\*(Aq => \*(Aqall\*(Aq},
+\&    {\*(Aqname\*(Aq => \*(AqChild chooses randomly\*(Aq, \*(Aqsend\*(Aq => \*(Aqrandom\*(Aq},
+\&    {\*(Aqname\*(Aq => \*(AqInvalid send instructions\*(Aq, \*(Aqsend\*(Aq => \*(AqNa Na Nana Na\*(Aq},
+\&    {\*(Aqname\*(Aq => \*(AqENV values in an array\*(Aq, \*(Aqsend\*(Aq => \*(Aqvalues\*(Aq},
+\&  );
+\&
+\&  INSTRUCTS:
+\&  foreach my $instruction (@instructions) {
+\&    $pm\->start($instruction\->{\*(Aqname\*(Aq}) and next INSTRUCTS;  # this time we are using an explicit, unique child process identifier
+\&
+\&    # last step in child processing
+\&    $pm\->finish(0) unless $instruction\->{\*(Aqsend\*(Aq};  # no data structure is sent unless this child is told what to send.
+\&
+\&    if ($instruction\->{\*(Aqsend\*(Aq} eq \*(Aqkeys\*(Aq) {
+\&      $pm\->finish(0, \ejoin(\*(Aq, \*(Aq, keys %ENV));
+\&
+\&    } elsif ($instruction\->{\*(Aqsend\*(Aq} eq \*(Aqvalues\*(Aq) {
+\&      $pm\->finish(0, [values %ENV]);  # kinda useless without knowing which keys they belong to...
+\&
+\&    } elsif ($instruction\->{\*(Aqsend\*(Aq} eq \*(Aqall\*(Aq) {
+\&      $pm\->finish(0, \e%ENV);  # remember, we are not "returning" anything, just copying the hash to disc
+\&
+\&    # demonstrate clearly that the child determines what type of reference to send
+\&    } elsif ($instruction\->{\*(Aqsend\*(Aq} eq \*(Aqrandom\*(Aq) {
+\&      my $string = q|I\*(Aqm just a string.|;
+\&      my @array = qw(I am an array);
+\&      my %hash = (type => \*(Aqassociative array\*(Aq, synonym => \*(Aqhash\*(Aq, cool => \*(Aqvery :)\*(Aq);
+\&      my $return_choice = (\*(Aqstring\*(Aq, \*(Aqarray\*(Aq, \*(Aqhash\*(Aq)[int(rand 3)];  # randomly choose return data type
+\&      $pm\->finish(0, \e$string) if ($return_choice eq \*(Aqstring\*(Aq);
+\&      $pm\->finish(0, \e@array) if ($return_choice eq \*(Aqarray\*(Aq);
+\&      $pm\->finish(0, \e%hash) if ($return_choice eq \*(Aqhash\*(Aq);
+\&
+\&    # as a responsible child, inform parent that their instruction was invalid
+\&    } else {
+\&      $pm\->finish(0, \eqq|Invalid instructions: "$instruction\->{\*(Aqsend\*(Aq}".|);  # ordinarily I wouldn\*(Aqt include invalid input in a response...
+\&    }
+\&  }
+\&  $pm\->wait_all_children;  # blocks until all forked processes have exited
+\&
+\&  # post fork processing of returned data structures
+\&  for (sort keys %retrieved_responses) {
+\&    print qq|Post processing "$_"...\en|;
+\&  }
+.Ve
+.SH "BUGS AND LIMITATIONS"
+.IX Header "BUGS AND LIMITATIONS"
+Do not use Parallel::ForkManager in an environment, where other child
+processes can affect the run of the main program, so using this module
+is not recommended in an environment where \fIfork()\fR / \fIwait()\fR is already used.
+.PP
+If you want to use more than one copies of the Parallel::ForkManager, then
+you have to make sure that all children processes are terminated, before you
+use the second object in the main program.
+.PP
+You are free to use a new copy of Parallel::ForkManager in the child
+processes, although I don't think it makes sense.
+.SH "CREDITS"
+.IX Header "CREDITS"
+.Vb 6
+\&  Michael Gang (bug report)
+\&  Noah Robin <sitz@onastick.net> (documentation tweaks)
+\&  Chuck Hirstius <chirstius@megapathdsl.net> (callback exit status, example)
+\&  Grant Hopwood <hopwoodg@valero.com> (win32 port)
+\&  Mark Southern <mark_southern@merck.com> (bugfix)
+\&  Ken Clarke <www.perlprogrammer.net>  (datastructure retrieval)
+.Ve
+.SH "AUTHORS"
+.IX Header "AUTHORS"
+.IP "\(bu" 4
+dLux (Szabo\*', Bala\*'zs) <dlux@dlux.hu>
+.IP "\(bu" 4
+Yanick Champoux <yanick@cpan.org>
+.IP "\(bu" 4
+Gabor Szabo <gabor@szabgab.com>
+.SH "COPYRIGHT AND LICENSE"
+.IX Header "COPYRIGHT AND LICENSE"
+This software is copyright (c) 2000 by Bala\*'zs Szabo\*'.
+.PP
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
diff --git a/Parallel-ForkManager-1.17/blib/script/.exists b/Parallel-ForkManager-1.17/blib/script/.exists
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/cpanfile b/Parallel-ForkManager-1.17/cpanfile
new file mode 100644 (file)
index 0000000..728c435
--- /dev/null
@@ -0,0 +1,33 @@
+requires "Carp" => "0";
+requires "File::Path" => "0";
+requires "File::Spec" => "0";
+requires "File::Temp" => "0";
+requires "POSIX" => "0";
+requires "Storable" => "0";
+requires "strict" => "0";
+
+on 'test' => sub {
+  requires "ExtUtils::MakeMaker" => "0";
+  requires "File::Spec" => "0";
+  requires "IO::Handle" => "0";
+  requires "IPC::Open3" => "0";
+  requires "Test::More" => "0.94";
+  requires "Test::Warn" => "0";
+  requires "perl" => "5.006";
+  requires "warnings" => "0";
+};
+
+on 'test' => sub {
+  recommends "CPAN::Meta" => "2.120900";
+};
+
+on 'configure' => sub {
+  requires "ExtUtils::MakeMaker" => "0";
+};
+
+on 'develop' => sub {
+  requires "Test::More" => "0.96";
+  requires "Test::PAUSE::Permissions" => "0";
+  requires "Test::Vars" => "0";
+  requires "warnings" => "0";
+};
diff --git a/Parallel-ForkManager-1.17/doap.xml b/Parallel-ForkManager-1.17/doap.xml
new file mode 100644 (file)
index 0000000..19ee374
--- /dev/null
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<Project
+  xmlns="http://usefulinc.com/ns/doap#"
+  xmlns:dc="http://purl.org/dc/terms/"
+  xmlns:foaf="http://xmlns.com/foaf/0.1/"
+  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+  >
+  <name>Parallel-ForkManager</name>
+  <shortdesc>A simple parallel processing fork manager</shortdesc>
+  <developer>
+    <foaf:Person>
+      <foaf:name>dLux (Szabó, Balázs)</foaf:name>
+      <foaf:mbox rdf:resource="mailto:dlux@dlux.hu" />
+    </foaf:Person>
+  </developer>
+  <developer>
+    <foaf:Person>
+      <foaf:name>Yanick Champoux</foaf:name>
+      <foaf:mbox rdf:resource="mailto:yanick@cpan.org" />
+    </foaf:Person>
+  </developer>
+  <developer>
+    <foaf:Person>
+      <foaf:name>Gabor Szabo</foaf:name>
+      <foaf:mbox rdf:resource="mailto:gabor@szabgab.com" />
+    </foaf:Person>
+  </developer>
+  <helper>
+    <foaf:Person>
+      <foaf:name>Ninebit</foaf:name>
+      <foaf:mbox rdf:resource="mailto:kevin@9b.io" />
+    </foaf:Person>
+  </helper>
+  <helper>
+    <foaf:Person>
+      <foaf:name>Shlomi Fish</foaf:name>
+      <foaf:mbox rdf:resource="mailto:shlomif@shlomifish.org" />
+    </foaf:Person>
+  </helper>
+  <license rdf:resource="http://dev.perl.org/licenses/" />
+  <homepage rdf:resource="https://github.com/dluxhu/perl-parallel-forkmanager" />
+  <bug-database rdf:resource="https://github.com/dluxhu/perl-parallel-forkmanager/issues" />
+  <repository>
+    <GitRepository>
+      <browse rdf:resource="https://github.com/dluxhu/perl-parallel-forkmanager" />
+      <location rdf:resource="https://github.com/dluxhu/perl-parallel-forkmanager.git" />
+    </GitRepository>
+  </repository>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.1</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2001-04-26</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.2</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2001-05-14</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.3</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2001-08-24</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.4</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2002-07-04</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.5</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2002-12-25</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.6</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2010-08-15</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.7</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2010-09-28</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.8</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2010-08-25</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7.9</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2010-11-01</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.5</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2000-10-18</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.6</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2000-11-30</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">0.7</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2001-04-04</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.0.0</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-12-23</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.01</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-12-23</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.02</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-12-24</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.03</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-03-06</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.04</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-09-03</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.05</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-09-18</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.06</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-12-24</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.07</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-11-10</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.08</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-01-07</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.09</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-01-08</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.10_1</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-01-22</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.10_2</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-01-25</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.11</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-01-30</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.12</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-02-23</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.13</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-05-11</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.14</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-05-17</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.15</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-07-08</dc:issued>
+    </Version>
+  </release>
+  <release>
+    <Version>
+      <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.16</revision>
+      <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2015-10-08</dc:issued>
+    </Version>
+  </release>
+  <programming-language>Perl</programming-language>
+</Project>
diff --git a/Parallel-ForkManager-1.17/examples/callback.pl b/Parallel-ForkManager-1.17/examples/callback.pl
new file mode 100755 (executable)
index 0000000..649ecf6
--- /dev/null
@@ -0,0 +1,48 @@
+#!/usr/bin/perl -w
+use lib '.';
+use strict;
+use Parallel::ForkManager;
+
+my $max_procs = 3;
+my @names = qw( Fred Jim Lily Steve Jessica Bob );
+# hash to resolve PID's back to child specific information
+
+my $pm = Parallel::ForkManager->new($max_procs);
+
+# Setup a callback for when a child finishes up so we can
+# get it's exit code
+$pm->run_on_finish(
+  sub { my ($pid, $exit_code, $ident) = @_;
+    print "** $ident just got out of the pool ".
+      "with PID $pid and exit code: $exit_code\n";
+  }
+);
+
+$pm->run_on_start(
+  sub { my ($pid,$ident)=@_;
+    print "** $ident started, pid: $pid\n";
+  }
+);
+
+$pm->run_on_wait(
+  sub {
+    print "** Have to wait for one children ...\n"
+  },
+  0.5,
+);
+
+foreach my $child ( 0 .. $#names ) {
+  my $pid = $pm->start($names[$child]) and next;
+
+  # This code is the child process
+  print "This is $names[$child], Child number $child\n";
+  sleep ( 2 * $child );
+  print "$names[$child], Child $child is about to get out...\n";
+  sleep 1;
+  $pm->finish($child); # pass an exit code to finish
+}
+
+print "Waiting for Children...\n";
+$pm->wait_all_children;
+print "Everybody is out of the pool!\n";
+
diff --git a/Parallel-ForkManager-1.17/examples/callback_data.pl b/Parallel-ForkManager-1.17/examples/callback_data.pl
new file mode 100644 (file)
index 0000000..97c6cfc
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Parallel::ForkManager;
+
+my $max_procs = 2;
+my @names = qw( Fred Jim );
+
+my $pm = Parallel::ForkManager->new($max_procs, @ARGV);
+
+# Setup a callback for when a child finishes up so we can
+# get it's exit code and any data it collected
+$pm->run_on_finish( sub {
+  my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+  print "$ident just got out of the pool ".
+    "with exit code: $exit_code and data: @$data_structure_reference\n";
+});
+
+$pm->run_on_start( sub {
+  my ($pid,$ident)=@_;
+  print "$ident started\n";
+});
+
+foreach my $child ( 0 .. $#names ) {
+  my $pid = $pm->start($names[$child]) and next;
+
+  # This code is the child process
+  # We can do here anything and obtain any data.
+  # The result can be any array or hash.
+  my @result = ($names[$child], length $names[$child]);
+  sleep 1+rand(3);
+
+  # pass an exit code and data stucture to finish
+  $pm->finish($child, \@result );
+}
+
+#print "Waiting for Children...\n";
+$pm->wait_all_children;
+print "Everybody is out of the pool!\n";
+
+
diff --git a/Parallel-ForkManager-1.17/examples/parallel_get.pl b/Parallel-ForkManager-1.17/examples/parallel_get.pl
new file mode 100755 (executable)
index 0000000..2a88458
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+if (not @ARGV) {
+  die <<"DIE";
+Usage: $0  URL URL...
+ e.g.: $0 http://cpan.metacpan.org/authors/id/D/DL/DLUX/Parallel-ForkManager-0.7.9.tar.gz
+DIE
+}
+
+use Parallel::ForkManager;
+use LWP::Simple;
+
+my $pm = Parallel::ForkManager->new(10);
+
+for my $link (@ARGV) {
+  $pm->start and next;
+
+  my ($fn) = $link =~ /^.*\/(.*?)$/;
+
+  if (!$fn) {
+    warn "Cannot determine filename from $fn\n";
+  } else {
+    $0 .= " $fn";
+    print "Getting $fn from $link\n";
+    my $rc = getstore($link, $fn);
+    print "$link downloaded. response code: $rc\n";
+  };
+
+  $pm->finish;
+};
diff --git a/Parallel-ForkManager-1.17/lib/Parallel/ForkManager.pm b/Parallel-ForkManager-1.17/lib/Parallel/ForkManager.pm
new file mode 100644 (file)
index 0000000..01db006
--- /dev/null
@@ -0,0 +1,852 @@
+package Parallel::ForkManager;
+our $AUTHORITY = 'cpan:DLUX';
+# ABSTRACT:  A simple parallel processing fork manager
+$Parallel::ForkManager::VERSION = '1.17';
+use POSIX ":sys_wait_h";
+use Storable qw(store retrieve);
+use File::Spec;
+use File::Temp ();
+use File::Path ();
+use Carp;
+
+use strict;
+
+sub new {
+  my ($c,$processes,$tempdir)=@_;
+
+  my $h={
+    max_proc   => $processes,
+    processes  => {},
+    in_child   => 0,
+    parent_pid => $$,
+    auto_cleanup => ($tempdir ? 0 : 1),
+    waitpid_blocking_sleep => 1,
+  };
+
+
+  # determine temporary directory for storing data structures
+  # add it to Parallel::ForkManager object so children can use it
+  # We don't let it clean up so it won't do it in the child process
+  # but we have our own DESTROY to do that.
+  if (not defined($tempdir) or not length($tempdir)) {
+    $tempdir = File::Temp::tempdir(CLEANUP => 0);
+  }
+  die qq|Temporary directory "$tempdir" doesn't exist or is not a directory.| unless (-e $tempdir && -d _);  # ensure temp dir exists and is indeed a directory
+  $h->{tempdir} = $tempdir;
+
+  return bless($h,ref($c)||$c);
+};
+
+sub start {
+  my ($s,$identification)=@_;
+
+  die "Cannot start another process while you are in the child process"
+    if $s->{in_child};
+  while ($s->{max_proc} && ( keys %{ $s->{processes} } ) >= $s->{max_proc}) {
+    $s->on_wait;
+    $s->wait_one_child(defined $s->{on_wait_period} ? &WNOHANG : undef);
+  };
+  $s->wait_children;
+  if ($s->{max_proc}) {
+    my $pid=fork();
+    die "Cannot fork: $!" if !defined $pid;
+    if ($pid) {
+      $s->{processes}->{$pid}=$identification;
+      $s->on_start($pid,$identification);
+    } else {
+      $s->{in_child}=1 if !$pid;
+    }
+    return $pid;
+  } else {
+    $s->{processes}->{$$}=$identification;
+    $s->on_start($$,$identification);
+    return 0; # Simulating the child which returns 0
+  }
+}
+
+sub finish {
+  my ($s, $x, $r)=@_;
+
+  if ( $s->{in_child} ) {
+    if (defined($r)) {  # store the child's data structure
+      my $storable_tempfile = File::Spec->catfile($s->{tempdir}, 'Parallel-ForkManager-' . $s->{parent_pid} . '-' . $$ . '.txt');
+      my $stored = eval { return &store($r, $storable_tempfile); };
+
+      # handle Storables errors, IE logcarp or carp returning undef, or die (via logcroak or croak)
+      if (not $stored or $@) {
+        warn(qq|The storable module was unable to store the child's data structure to the temp file "$storable_tempfile":  | . join(', ', $@));
+      }
+    }
+    CORE::exit($x || 0);
+  }
+  if ($s->{max_proc} == 0) { # max_proc == 0
+    $s->on_finish($$, $x ,$s->{processes}->{$$}, 0, 0, $r);
+    delete $s->{processes}->{$$};
+  }
+  return 0;
+}
+
+sub wait_children {
+  my ($s)=@_;
+
+  return if !keys %{$s->{processes}};
+  my $kid;
+  do {
+    $kid = $s->wait_one_child(&WNOHANG);
+  } while defined $kid and ( $kid > 0 or $kid < -1 ); # AS 5.6/Win32 returns negative PIDs
+};
+
+*wait_childs=*wait_children; # compatibility
+*reap_finished_children=*wait_children; # behavioral synonym for clarity
+
+sub wait_one_child {
+  my ($s,$par)=@_;
+
+  my $kid;
+  while (1) {
+    $kid = $s->_waitpid(-1,$par||=0);
+
+    last unless defined $kid;
+
+    last if $kid == 0 || $kid == -1; # AS 5.6/Win32 returns negative PIDs
+    redo if !exists $s->{processes}->{$kid};
+    my $id = delete $s->{processes}->{$kid};
+
+    # retrieve child data structure, if any
+    my $retrieved = undef;
+    my $storable_tempfile = File::Spec->catfile($s->{tempdir}, 'Parallel-ForkManager-' . $$ . '-' . $kid . '.txt');
+    if (-e $storable_tempfile) {  # child has option of not storing anything, so we need to see if it did or not
+      $retrieved = eval { return &retrieve($storable_tempfile); };
+
+      # handle Storables errors
+      if (not $retrieved or $@) {
+        warn(qq|The storable module was unable to retrieve the child's data structure from the temporary file "$storable_tempfile":  | . join(', ', $@));
+      }
+
+      # clean up after ourselves
+      unlink $storable_tempfile;
+    }
+
+    $s->on_finish( $kid, $? >> 8 , $id, $? & 0x7f, $? & 0x80 ? 1 : 0, $retrieved);
+    last;
+  }
+  $kid;
+};
+
+sub wait_all_children {
+  my ($s)=@_;
+
+  while (keys %{ $s->{processes} }) {
+    $s->on_wait;
+    $s->wait_one_child(defined $s->{on_wait_period} ? &WNOHANG : undef);
+  };
+}
+
+*wait_all_childs=*wait_all_children; # compatibility;
+
+sub max_procs { $_[0]->{max_proc}; }
+
+sub is_child  { $_[0]->{in_child} }
+
+sub is_parent { !$_[0]->{in_child} }
+
+sub running_procs {
+    my $self = shift;
+
+    my @pids = keys %{ $self->{processes} };
+    return @pids;
+}
+
+sub wait_for_available_procs {
+    my( $self, $nbr ) = @_;
+    $nbr ||= 1;
+
+    croak "nbr processes '$nbr' higher than the max nbr of processes (@{[ $self->max_procs ]})"
+        if $nbr > $self->max_procs;
+
+    $self->wait_one_child until $self->max_procs - $self->running_procs >= $nbr;
+}
+
+sub run_on_finish {
+  my ($s,$code,$pid)=@_;
+
+  $s->{on_finish}->{$pid || 0}=$code;
+}
+
+sub on_finish {
+  my ($s,$pid,@par)=@_;
+
+  my $code=$s->{on_finish}->{$pid} || $s->{on_finish}->{0} or return 0;
+  $code->($pid,@par);
+};
+
+sub run_on_wait {
+  my ($s,$code, $period)=@_;
+
+  $s->{on_wait}=$code;
+  $s->{on_wait_period} = $period;
+}
+
+sub on_wait {
+  my ($s)=@_;
+
+  if(ref($s->{on_wait}) eq 'CODE') {
+    $s->{on_wait}->();
+    if (defined $s->{on_wait_period}) {
+        local $SIG{CHLD} = sub { } if ! defined $SIG{CHLD};
+        select undef, undef, undef, $s->{on_wait_period}
+    };
+  };
+};
+
+sub run_on_start {
+  my ($s,$code)=@_;
+
+  $s->{on_start}=$code;
+}
+
+sub on_start {
+  my ($s,@par)=@_;
+
+  $s->{on_start}->(@par) if ref($s->{on_start}) eq 'CODE';
+};
+
+sub set_max_procs {
+  my ($s, $mp)=@_;
+
+  $s->{max_proc} = $mp;
+}
+
+sub set_waitpid_blocking_sleep {
+    my( $self, $period ) = @_;
+    $self->{waitpid_blocking_sleep} = $period;
+}
+
+sub waitpid_blocking_sleep {
+    $_[0]->{waitpid_blocking_sleep};
+}
+
+sub _waitpid { # Call waitpid() in the standard Unix fashion.
+    my( $self, undef, $flag ) = @_;
+
+    return $flag ? $self->_waitpid_non_blocking : $self->_waitpid_blocking;
+}
+
+sub _waitpid_non_blocking {
+    my $self = shift;
+
+    for my $pid ( $self->running_procs ) {
+        my $p = waitpid $pid, &WNOHANG or next;
+
+        return $pid if $p != -1;
+
+        warn "child process '$pid' disappeared. A call to `waitpid` outside of Parallel::ForkManager might have reaped it.\n";
+        # it's gone. let's clean the process entry
+        delete $self->{processes}{$pid};
+    }
+
+    return;
+}
+
+sub _waitpid_blocking {
+    my $self = shift;
+
+    # pseudo-blocking
+    if( my $sleep_period = $self->{waitpid_blocking_sleep} ) {
+        while() {
+            my $pid = $self->_waitpid_non_blocking;
+
+            return $pid if defined $pid;
+
+            return unless $self->running_procs;
+
+            select undef, undef, undef, $sleep_period;
+        }
+    }
+
+    return waitpid -1, 0;
+}
+
+sub DESTROY {
+  my ($self) = @_;
+
+  if ($self->{auto_cleanup} && $self->{parent_pid} == $$ && -d $self->{tempdir}) {
+    File::Path::remove_tree($self->{tempdir});
+  }
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Parallel::ForkManager - A simple parallel processing fork manager
+
+=head1 VERSION
+
+version 1.17
+
+=head1 SYNOPSIS
+
+  use Parallel::ForkManager;
+
+  my $pm = Parallel::ForkManager->new($MAX_PROCESSES);
+
+  DATA_LOOP:
+  foreach my $data (@all_data) {
+    # Forks and returns the pid for the child:
+    my $pid = $pm->start and next DATA_LOOP;
+
+    ... do some work with $data in the child process ...
+
+    $pm->finish; # Terminates the child process
+  }
+
+=head1 DESCRIPTION
+
+This module is intended for use in operations that can be done in parallel
+where the number of processes to be forked off should be limited. Typical
+use is a downloader which will be retrieving hundreds/thousands of files.
+
+The code for a downloader would look something like this:
+
+  use LWP::Simple;
+  use Parallel::ForkManager;
+
+  ...
+
+  my @links=(
+    ["http://www.foo.bar/rulez.data","rulez_data.txt"],
+    ["http://new.host/more_data.doc","more_data.doc"],
+    ...
+  );
+
+  ...
+
+  # Max 30 processes for parallel download
+  my $pm = Parallel::ForkManager->new(30);
+
+  LINKS:
+  foreach my $linkarray (@links) {
+    $pm->start and next LINKS; # do the fork
+
+    my ($link, $fn) = @$linkarray;
+    warn "Cannot get $fn from $link"
+      if getstore($link, $fn) != RC_OK;
+
+    $pm->finish; # do the exit in the child process
+  }
+  $pm->wait_all_children;
+
+First you need to instantiate the ForkManager with the "new" constructor.
+You must specify the maximum number of processes to be created. If you
+specify 0, then NO fork will be done; this is good for debugging purposes.
+
+Next, use $pm->start to do the fork. $pm returns 0 for the child process,
+and child pid for the parent process (see also L<perlfunc(1p)/fork()>).
+The "and next" skips the internal loop in the parent process. NOTE:
+$pm->start dies if the fork fails.
+
+$pm->finish terminates the child process (assuming a fork was done in the
+"start").
+
+NOTE: You cannot use $pm->start if you are already in the child process.
+If you want to manage another set of subprocesses in the child process,
+you must instantiate another Parallel::ForkManager object!
+
+=head1 METHODS
+
+The comment letter indicates where the method should be run. P for parent,
+C for child.
+
+=over 5
+
+=item new $processes
+
+Instantiate a new Parallel::ForkManager object. You must specify the maximum
+number of children to fork off. If you specify 0 (zero), then no children
+will be forked. This is intended for debugging purposes.
+
+The optional second parameter, $tempdir, is only used if you want the
+children to send back a reference to some data (see RETRIEVING DATASTRUCTURES
+below). If not provided, it is set via a call to L<File::Temp>::tempdir().
+
+The new method will die if the temporary directory does not exist or it is not
+a directory.
+
+=item start [ $process_identifier ]
+
+This method does the fork. It returns the pid of the child process for
+the parent, and 0 for the child process. If the $processes parameter
+for the constructor is 0 then, assuming you're in the child process,
+$pm->start simply returns 0.
+
+An optional $process_identifier can be provided to this method... It is used by
+the "run_on_finish" callback (see CALLBACKS) for identifying the finished
+process.
+
+=item finish [ $exit_code [, $data_structure_reference] ]
+
+Closes the child process by exiting and accepts an optional exit code
+(default exit code is 0) which can be retrieved in the parent via callback.
+If the second optional parameter is provided, the child attempts to send
+it's contents back to the parent. If you use the program in debug mode
+($processes == 0), this method just calls the callback.
+
+If the $data_structure_reference is provided, then it is serialized and
+passed to the parent process. See RETRIEVING DATASTRUCTURES for more info.
+
+=item set_max_procs $processes
+
+Allows you to set a new maximum number of children to maintain.
+
+=item wait_all_children
+
+You can call this method to wait for all the processes which have been
+forked. This is a blocking wait.
+
+=item reap_finished_children
+
+This is a non-blocking call to reap children and execute callbacks independent
+of calls to "start" or "wait_all_children". Use this in scenarios where "start"
+is called infrequently but you would like the callbacks executed quickly.
+
+=item is_parent
+
+Returns C<true> if within the parent or C<false> if within the child.
+
+=item is_child
+
+Returns C<true> if within the child or C<false> if within the parent.
+
+=item max_procs 
+
+Returns the maximal number of processes the object will fork.
+
+=item running_procs
+
+Returns the pids of the forked processes currently monitored by the
+C<Parallel::ForkManager>. Note that children are still reported as running
+until the fork manager harvest them, via the next call to
+C<start> or C<wait_all_children>.
+
+    my @pids = $pm->running_procs;
+
+    my $nbr_children =- $pm->running_procs;
+
+=item wait_for_available_procs( $n )
+
+Wait until C<$n> available process slots are available.
+If C<$n> is not given, defaults to I<1>.
+
+=item waitpid_blocking_sleep 
+
+Returns the sleep period, in seconds, of the pseudo-blocking calls. The sleep
+period can be a fraction of second. 
+
+Returns C<0> if disabled. 
+
+Defaults to 1 second.
+
+See I<BLOCKING CALLS> for more details.
+
+=item set_waitpid_blocking_sleep $seconds
+
+Sets the the sleep period, in seconds, of the pseudo-blocking calls.
+Set to C<0> to disable.
+
+See I<BLOCKING CALLS> for more details.
+
+=back
+
+=head1 CALLBACKS
+
+You can define callbacks in the code, which are called on events like starting
+a process or upon finish. Declare these before the first call to start().
+
+The callbacks can be defined with the following methods:
+
+=over 4
+
+=item run_on_finish $code [, $pid ]
+
+You can define a subroutine which is called when a child is terminated. It is
+called in the parent process.
+
+The parameters of the $code are the following:
+
+  - pid of the process, which is terminated
+  - exit code of the program
+  - identification of the process (if provided in the "start" method)
+  - exit signal (0-127: signal name)
+  - core dump (1 if there was core dump at exit)
+  - datastructure reference or undef (see RETRIEVING DATASTRUCTURES)
+
+=item run_on_start $code
+
+You can define a subroutine which is called when a child is started. It called
+after the successful startup of a child in the parent process.
+
+The parameters of the $code are the following:
+
+  - pid of the process which has been started
+  - identification of the process (if provided in the "start" method)
+
+=item run_on_wait $code, [$period]
+
+You can define a subroutine which is called when the child process needs to wait
+for the startup. If $period is not defined, then one call is done per
+child. If $period is defined, then $code is called periodically and the
+module waits for $period seconds between the two calls. Note, $period can be
+fractional number also. The exact "$period seconds" is not guaranteed,
+signals can shorten and the process scheduler can make it longer (on busy
+systems).
+
+The $code called in the "start" and the "wait_all_children" method also.
+
+No parameters are passed to the $code on the call.
+
+=back
+
+=head1 BLOCKING CALLS
+
+When it comes to waiting for child processes to terminate, C<Parallel::ForkManager> is between 
+a fork and a hard place (if you excuse the terrible pun). The underlying Perl C<waitpid> function
+that the module relies on can block until either one specific or any child process 
+terminate, but not for a process part of a given group.
+
+This means that the module can do one of two things when it waits for 
+one of its child processes to terminate:
+
+=over
+
+=item Only wait for its own child processes
+
+This is done via a loop using a C<waitpid> non-blocking call and a sleep statement.
+The code does something along the lines of
+
+    while(1) {
+        if ( any of the P::FM child process terminated ) {
+            return its pid
+        }
+
+        sleep $sleep_period
+    }
+
+This is the default behavior that the module will use.
+This is not the most efficient way to wait for child processes, but it's
+the safest way to ensure that C<Parallel::ForkManager> won't interfere with 
+any other part of the codebase. 
+
+The sleep period is set via the method C<set_waitpid_blocking_sleep>.
+
+=item Block until any process terminate
+
+Alternatively, C<Parallel::ForkManager> can call C<waitpid> such that it will
+block until any child process terminate. If the child process was not one of
+the monitored subprocesses, the wait will resume. This is more efficient, but mean
+that C<P::FM> can captures (and discards) the termination notification that a different
+part of the code might be waiting for. 
+
+If this is a race condition
+that doesn't apply to your codebase, you can set the 
+I<waitpid_blocking_sleep> period to C<0>, which will enable C<waitpid> call blocking.
+
+    my $pm = Parallel::ForkManager->new( 4 );
+
+    $pm->set_waitpid_blocking_sleep(0);  # true blocking calls enabled
+
+    for ( 1..100 ) {
+        $pm->start and next;
+
+        ...; # do work
+
+        $pm->finish;
+    }
+
+=back
+
+=head1 RETRIEVING DATASTRUCTURES from child processes
+
+The ability for the parent to retrieve data structures is new as of version
+0.7.6.
+
+Each child process may optionally send 1 data structure back to the parent.
+By data structure, we mean a reference to a string, hash or array. The
+contents of the data structure are written out to temporary files on disc
+using the L<Storable> modules' store() method. The reference is then
+retrieved from within the code you send to the run_on_finish callback.
+
+The data structure can be any scalar perl data structure which makes sense:
+string, numeric value or a reference to an array, hash or object.
+
+There are 2 steps involved in retrieving data structures:
+
+1) A reference to the data structure the child wishes to send back to the
+parent is provided as the second argument to the finish() call. It is up
+to the child to decide whether or not to send anything back to the parent.
+
+2) The data structure reference is retrieved using the callback provided in
+the run_on_finish() method.
+
+Keep in mind that data structure retrieval is not the same as returning a
+data structure from a method call. That is not what actually occurs. The
+data structure referenced in a given child process is serialized and
+written out to a file by L<Storable>. The file is subsequently read back
+into memory and a new data structure belonging to the parent process is
+created. Please consider the performance penality it can imply, so try to
+keep the returned structure small.
+
+=head1 EXAMPLES
+
+=head2 Parallel get
+
+This small example can be used to get URLs in parallel.
+
+  use Parallel::ForkManager;
+  use LWP::Simple;
+
+  my $pm = Parallel::ForkManager->new(10);
+
+  LINKS:
+  for my $link (@ARGV) {
+    $pm->start and next LINKS;
+    my ($fn) = $link =~ /^.*\/(.*?)$/;
+    if (!$fn) {
+      warn "Cannot determine filename from $fn\n";
+    } else {
+      $0 .= " " . $fn;
+      print "Getting $fn from $link\n";
+      my $rc = getstore($link, $fn);
+      print "$link downloaded. response code: $rc\n";
+    };
+    $pm->finish;
+  };
+
+=head2 Callbacks
+
+Example of a program using callbacks to get child exit codes:
+
+  use strict;
+  use Parallel::ForkManager;
+
+  my $max_procs = 5;
+  my @names = qw( Fred Jim Lily Steve Jessica Bob Dave Christine Rico Sara );
+  # hash to resolve PID's back to child specific information
+
+  my $pm = Parallel::ForkManager->new($max_procs);
+
+  # Setup a callback for when a child finishes up so we can
+  # get it's exit code
+  $pm->run_on_finish( sub {
+      my ($pid, $exit_code, $ident) = @_;
+      print "** $ident just got out of the pool ".
+        "with PID $pid and exit code: $exit_code\n";
+  });
+
+  $pm->run_on_start( sub {
+      my ($pid, $ident)=@_;
+      print "** $ident started, pid: $pid\n";
+  });
+
+  $pm->run_on_wait( sub {
+      print "** Have to wait for one children ...\n"
+    },
+    0.5
+  );
+
+  NAMES:
+  foreach my $child ( 0 .. $#names ) {
+    my $pid = $pm->start($names[$child]) and next NAMES;
+
+    # This code is the child process
+    print "This is $names[$child], Child number $child\n";
+    sleep ( 2 * $child );
+    print "$names[$child], Child $child is about to get out...\n";
+    sleep 1;
+    $pm->finish($child); # pass an exit code to finish
+  }
+
+  print "Waiting for Children...\n";
+  $pm->wait_all_children;
+  print "Everybody is out of the pool!\n";
+
+=head2 Data structure retrieval
+
+In this simple example, each child sends back a string reference.
+
+  use Parallel::ForkManager 0.7.6;
+  use strict;
+
+  my $pm = Parallel::ForkManager->new(2, '/server/path/to/temp/dir/');
+
+  # data structure retrieval and handling
+  $pm -> run_on_finish ( # called BEFORE the first call to start()
+    sub {
+      my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+
+      # retrieve data structure from child
+      if (defined($data_structure_reference)) {  # children are not forced to send anything
+        my $string = ${$data_structure_reference};  # child passed a string reference
+        print "$string\n";
+      }
+      else {  # problems occuring during storage or retrieval will throw a warning
+        print qq|No message received from child process $pid!\n|;
+      }
+    }
+  );
+
+  # prep random statement components
+  my @foods = ('chocolate', 'ice cream', 'peanut butter', 'pickles', 'pizza', 'bacon', 'pancakes', 'spaghetti', 'cookies');
+  my @preferences = ('loves', q|can't stand|, 'always wants more', 'will walk 100 miles for', 'only eats', 'would starve rather than eat');
+
+  # run the parallel processes
+  PERSONS:
+  foreach my $person (qw(Fred Wilma Ernie Bert Lucy Ethel Curly Moe Larry)) {
+    $pm->start() and next PERSONS;
+
+    # generate a random statement about food preferences
+    my $statement = $person . ' ' . $preferences[int(rand @preferences)] . ' ' . $foods[int(rand @foods)];
+
+    # send it back to the parent process
+    $pm->finish(0, \$statement);  # note that it's a scalar REFERENCE, not the scalar itself
+  }
+  $pm->wait_all_children;
+
+A second datastructure retrieval example demonstrates how children decide
+whether or not to send anything back, what to send and how the parent should
+process whatever is retrieved.
+
+=for example begin
+
+  use Parallel::ForkManager 0.7.6;
+  use Data::Dumper;  # to display the data structures retrieved.
+  use strict;
+
+  my $pm = Parallel::ForkManager->new(20);  # using the system temp dir $L<File::Temp::tempdir()
+
+  # data structure retrieval and handling
+  my %retrieved_responses = ();  # for collecting responses
+  $pm -> run_on_finish (
+    sub {
+      my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data_structure_reference) = @_;
+
+      # see what the child sent us, if anything
+      if (defined($data_structure_reference)) {  # test rather than assume child sent anything
+        my $reftype = ref($data_structure_reference);
+        print qq|ident "$ident" returned a "$reftype" reference.\n\n|;
+        if (1) {  # simple on/off switch to display the contents
+          print &Dumper($data_structure_reference) . qq|end of "$ident" sent structure\n\n|;
+        }
+
+        # we can also collect retrieved data structures for processing after all children have exited
+        $retrieved_responses{$ident} = $data_structure_reference;
+      } else {
+        print qq|ident "$ident" did not send anything.\n\n|;
+      }
+    }
+  );
+
+  # generate a list of instructions
+  my @instructions = (  # a unique identifier and what the child process should send
+    {'name' => '%ENV keys as a string', 'send' => 'keys'},
+    {'name' => 'Send Nothing'},  # not instructing the child to send anything back to the parent
+    {'name' => 'Childs %ENV', 'send' => 'all'},
+    {'name' => 'Child chooses randomly', 'send' => 'random'},
+    {'name' => 'Invalid send instructions', 'send' => 'Na Na Nana Na'},
+    {'name' => 'ENV values in an array', 'send' => 'values'},
+  );
+
+  INSTRUCTS:
+  foreach my $instruction (@instructions) {
+    $pm->start($instruction->{'name'}) and next INSTRUCTS;  # this time we are using an explicit, unique child process identifier
+
+    # last step in child processing
+    $pm->finish(0) unless $instruction->{'send'};  # no data structure is sent unless this child is told what to send.
+
+    if ($instruction->{'send'} eq 'keys') {
+      $pm->finish(0, \join(', ', keys %ENV));
+
+    } elsif ($instruction->{'send'} eq 'values') {
+      $pm->finish(0, [values %ENV]);  # kinda useless without knowing which keys they belong to...
+
+    } elsif ($instruction->{'send'} eq 'all') {
+      $pm->finish(0, \%ENV);  # remember, we are not "returning" anything, just copying the hash to disc
+
+    # demonstrate clearly that the child determines what type of reference to send
+    } elsif ($instruction->{'send'} eq 'random') {
+      my $string = q|I'm just a string.|;
+      my @array = qw(I am an array);
+      my %hash = (type => 'associative array', synonym => 'hash', cool => 'very :)');
+      my $return_choice = ('string', 'array', 'hash')[int(rand 3)];  # randomly choose return data type
+      $pm->finish(0, \$string) if ($return_choice eq 'string');
+      $pm->finish(0, \@array) if ($return_choice eq 'array');
+      $pm->finish(0, \%hash) if ($return_choice eq 'hash');
+
+    # as a responsible child, inform parent that their instruction was invalid
+    } else {
+      $pm->finish(0, \qq|Invalid instructions: "$instruction->{'send'}".|);  # ordinarily I wouldn't include invalid input in a response...
+    }
+  }
+  $pm->wait_all_children;  # blocks until all forked processes have exited
+
+  # post fork processing of returned data structures
+  for (sort keys %retrieved_responses) {
+    print qq|Post processing "$_"...\n|;
+  }
+
+=for example end
+
+=head1 BUGS AND LIMITATIONS
+
+Do not use Parallel::ForkManager in an environment, where other child
+processes can affect the run of the main program, so using this module
+is not recommended in an environment where fork() / wait() is already used.
+
+If you want to use more than one copies of the Parallel::ForkManager, then
+you have to make sure that all children processes are terminated, before you
+use the second object in the main program.
+
+You are free to use a new copy of Parallel::ForkManager in the child
+processes, although I don't think it makes sense.
+
+=head1 CREDITS
+
+  Michael Gang (bug report)
+  Noah Robin <sitz@onastick.net> (documentation tweaks)
+  Chuck Hirstius <chirstius@megapathdsl.net> (callback exit status, example)
+  Grant Hopwood <hopwoodg@valero.com> (win32 port)
+  Mark Southern <mark_southern@merck.com> (bugfix)
+  Ken Clarke <www.perlprogrammer.net>  (datastructure retrieval)
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+dLux (Szabó, Balázs) <dlux@dlux.hu>
+
+=item *
+
+Yanick Champoux <yanick@cpan.org>
+
+=item *
+
+Gabor Szabo <gabor@szabgab.com>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2000 by Balázs Szabó.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
diff --git a/Parallel-ForkManager-1.17/pm_to_blib b/Parallel-ForkManager-1.17/pm_to_blib
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Parallel-ForkManager-1.17/t/00-compile.t b/Parallel-ForkManager-1.17/t/00-compile.t
new file mode 100644 (file)
index 0000000..faac267
--- /dev/null
@@ -0,0 +1,51 @@
+use 5.006;
+use strict;
+use warnings;
+
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.052
+
+use Test::More;
+
+plan tests => 1 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
+
+my @module_files = (
+    'Parallel/ForkManager.pm'
+);
+
+
+
+# no fake home requested
+
+my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib';
+
+use File::Spec;
+use IPC::Open3;
+use IO::Handle;
+
+open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
+
+my @warnings;
+for my $lib (@module_files)
+{
+    # see L<perlfaq8/How can I capture STDERR from an external command?>
+    my $stderr = IO::Handle->new;
+
+    my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]");
+    binmode $stderr, ':crlf' if $^O eq 'MSWin32';
+    my @_warnings = <$stderr>;
+    waitpid($pid, 0);
+    is($?, 0, "$lib loaded ok");
+
+    if (@_warnings)
+    {
+        warn @_warnings;
+        push @warnings, @_warnings;
+    }
+}
+
+
+
+is(scalar(@warnings), 0, 'no warnings found')
+    or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING};
+
+
diff --git a/Parallel-ForkManager-1.17/t/00-load.t b/Parallel-ForkManager-1.17/t/00-load.t
new file mode 100644 (file)
index 0000000..5d2983a
--- /dev/null
@@ -0,0 +1,41 @@
+use strict;
+use warnings;
+
+use Test::More tests => 4;
+use Parallel::ForkManager;
+use File::Temp qw(tempdir);
+
+my @numbers = (1 .. 20);
+
+for my $processes ( 1, 3 ) {
+    for my $pseudo_block ( 0, 1 ) {
+        my $chrono = time;
+        is_deeply count($processes,$pseudo_block) => \@numbers,
+            "procs: $processes, pseudo-block: $pseudo_block";
+        $chrono = time - $chrono;
+        diag "time: $chrono seconds";
+    };
+}
+
+
+sub count {
+    my ($concurrency,$blocking_time) = @_;
+
+    my $dir = tempdir(CLEANUP => 1);
+
+    my $fork = Parallel::ForkManager->new( $concurrency );
+    $fork->set_waitpid_blocking_sleep( $blocking_time );
+
+    foreach my $n (@numbers) {
+           my $pid = $fork->start and next;
+        open my $fh, '>', "$dir/$n" or die;
+        close $fh or die;
+           $fork->finish;
+    }
+    $fork->wait_all_children;
+    opendir my $dh, $dir or die;
+    my @results = grep { $_ !~ /\./ } readdir $dh;
+    closedir $dh or die;
+    return [sort {$a <=> $b} @results];
+}
+
diff --git a/Parallel-ForkManager-1.17/t/00-report-prereqs.dd b/Parallel-ForkManager-1.17/t/00-report-prereqs.dd
new file mode 100644 (file)
index 0000000..abfe35e
--- /dev/null
@@ -0,0 +1,43 @@
+do { my $x = {
+       'configure' => {
+                        'requires' => {
+                                        'ExtUtils::MakeMaker' => '0'
+                                      }
+                      },
+       'develop' => {
+                      'requires' => {
+                                      'Test::More' => '0.96',
+                                      'Test::PAUSE::Permissions' => '0',
+                                      'Test::Vars' => '0',
+                                      'warnings' => '0'
+                                    }
+                    },
+       'runtime' => {
+                      'requires' => {
+                                      'Carp' => '0',
+                                      'File::Path' => '0',
+                                      'File::Spec' => '0',
+                                      'File::Temp' => '0',
+                                      'POSIX' => '0',
+                                      'Storable' => '0',
+                                      'strict' => '0'
+                                    }
+                    },
+       'test' => {
+                   'recommends' => {
+                                     'CPAN::Meta' => '2.120900'
+                                   },
+                   'requires' => {
+                                   'ExtUtils::MakeMaker' => '0',
+                                   'File::Spec' => '0',
+                                   'IO::Handle' => '0',
+                                   'IPC::Open3' => '0',
+                                   'Test::More' => '0.94',
+                                   'Test::Warn' => '0',
+                                   'perl' => '5.006',
+                                   'warnings' => '0'
+                                 }
+                 }
+     };
+  $x;
+ }
\ No newline at end of file
diff --git a/Parallel-ForkManager-1.17/t/00-report-prereqs.t b/Parallel-ForkManager-1.17/t/00-report-prereqs.t
new file mode 100644 (file)
index 0000000..d8d15ba
--- /dev/null
@@ -0,0 +1,183 @@
+#!perl
+
+use strict;
+use warnings;
+
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.021
+
+use Test::More tests => 1;
+
+use ExtUtils::MakeMaker;
+use File::Spec;
+
+# from $version::LAX
+my $lax_version_re =
+    qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )?
+            |
+            (?:\.[0-9]+) (?:_[0-9]+)?
+        ) | (?:
+            v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )?
+            |
+            (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)?
+        )
+    )/x;
+
+# hide optional CPAN::Meta modules from prereq scanner
+# and check if they are available
+my $cpan_meta = "CPAN::Meta";
+my $cpan_meta_pre = "CPAN::Meta::Prereqs";
+my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic
+
+# Verify requirements?
+my $DO_VERIFY_PREREQS = 1;
+
+sub _max {
+    my $max = shift;
+    $max = ( $_ > $max ) ? $_ : $max for @_;
+    return $max;
+}
+
+sub _merge_prereqs {
+    my ($collector, $prereqs) = @_;
+
+    # CPAN::Meta::Prereqs object
+    if (ref $collector eq $cpan_meta_pre) {
+        return $collector->with_merged_prereqs(
+            CPAN::Meta::Prereqs->new( $prereqs )
+        );
+    }
+
+    # Raw hashrefs
+    for my $phase ( keys %$prereqs ) {
+        for my $type ( keys %{ $prereqs->{$phase} } ) {
+            for my $module ( keys %{ $prereqs->{$phase}{$type} } ) {
+                $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module};
+            }
+        }
+    }
+
+    return $collector;
+}
+
+my @include = qw(
+
+);
+
+my @exclude = qw(
+
+);
+
+# Add static prereqs to the included modules list
+my $static_prereqs = do 't/00-report-prereqs.dd';
+
+# Merge all prereqs (either with ::Prereqs or a hashref)
+my $full_prereqs = _merge_prereqs(
+    ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
+    $static_prereqs
+);
+
+# Add dynamic prereqs to the included modules list (if we can)
+my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
+if ( $source && $HAS_CPAN_META ) {
+    if ( my $meta = eval { CPAN::Meta->load_file($source) } ) {
+        $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs);
+    }
+}
+else {
+    $source = 'static metadata';
+}
+
+my @full_reports;
+my @dep_errors;
+my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
+
+# Add static includes into a fake section
+for my $mod (@include) {
+    $req_hash->{other}{modules}{$mod} = 0;
+}
+
+for my $phase ( qw(configure build test runtime develop other) ) {
+    next unless $req_hash->{$phase};
+    next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
+
+    for my $type ( qw(requires recommends suggests conflicts modules) ) {
+        next unless $req_hash->{$phase}{$type};
+
+        my $title = ucfirst($phase).' '.ucfirst($type);
+        my @reports = [qw/Module Want Have/];
+
+        for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) {
+            next if $mod eq 'perl';
+            next if grep { $_ eq $mod } @exclude;
+
+            my $file = $mod;
+            $file =~ s{::}{/}g;
+            $file .= ".pm";
+            my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC;
+
+            my $want = $req_hash->{$phase}{$type}{$mod};
+            $want = "undef" unless defined $want;
+            $want = "any" if !$want && $want == 0;
+
+            my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required";
+
+            if ($prefix) {
+                my $have = MM->parse_version( File::Spec->catfile($prefix, $file) );
+                $have = "undef" unless defined $have;
+                push @reports, [$mod, $want, $have];
+
+                if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) {
+                    if ( $have !~ /\A$lax_version_re\z/ ) {
+                        push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)";
+                    }
+                    elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) {
+                        push @dep_errors, "$mod version '$have' is not in required range '$want'";
+                    }
+                }
+            }
+            else {
+                push @reports, [$mod, $want, "missing"];
+
+                if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) {
+                    push @dep_errors, "$mod is not installed ($req_string)";
+                }
+            }
+        }
+
+        if ( @reports ) {
+            push @full_reports, "=== $title ===\n\n";
+
+            my $ml = _max( map { length $_->[0] } @reports );
+            my $wl = _max( map { length $_->[1] } @reports );
+            my $hl = _max( map { length $_->[2] } @reports );
+
+            if ($type eq 'modules') {
+                splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl];
+                push @full_reports, map { sprintf("    %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports;
+            }
+            else {
+                splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
+                push @full_reports, map { sprintf("    %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
+            }
+
+            push @full_reports, "\n";
+        }
+    }
+}
+
+if ( @full_reports ) {
+    diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports;
+}
+
+if ( @dep_errors ) {
+    diag join("\n",
+        "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n",
+        "The following REQUIRED prerequisites were not satisfied:\n",
+        @dep_errors,
+        "\n"
+    );
+}
+
+pass;
+
+# vim: ts=4 sts=4 sw=4 et:
diff --git a/Parallel-ForkManager-1.17/t/01-utf8-all.t b/Parallel-ForkManager-1.17/t/01-utf8-all.t
new file mode 100644 (file)
index 0000000..4acd4e9
--- /dev/null
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Parallel::ForkManager;
+
+plan skip_all => 'This is a bug in perl itself on Windows' if $^O eq 'MSWin32';
+# It is broken on 5.16.2 and on blead Perl:
+# It was reported to the Perl 5 porters:
+# http://www.nntp.perl.org/group/perl.perl5.porters/2012/12/msg196821.html
+
+eval "use utf8::all";
+plan skip_all => 'Need utf8::all for this test crashing on Windows' if ($@);
+plan tests => 1;
+
+my $fork = Parallel::ForkManager->new( 1 );
+foreach (1) {
+    my $pid = $fork->start and next;
+       $fork->finish;
+}
+$fork->wait_all_children;
+
+ok(1);
+
diff --git a/Parallel-ForkManager-1.17/t/02-callback.t b/Parallel-ForkManager-1.17/t/02-callback.t
new file mode 100644 (file)
index 0000000..652aa00
--- /dev/null
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+
+use Test::More tests => 2;
+
+diag 'This test can take 10-20 seconds, please wait. Started at ' . localtime;
+
+my @out = qx{$^X -Ilib examples/callback.pl};
+$_ =~ s/pid:\s*-?\d+/pid:/g for @out;
+$_ =~ s/PID\s*-?\d+/PID/g for @out;
+my @wait  = grep { /Have to wait for one children/ } @out;
+@out = grep { !/Have to wait for one children/ } @out;
+@out = sort @out;
+cmp_ok scalar(@wait), '>', 10, 'Have to wait for one children at least 10 times';
+
+
+my @expected = do { open my $fh, '<', 't/callback.txt'; <$fh> };
+$_ =~ s/pid:\s*-?\d+/pid:/g for @expected;
+$_ =~ s/PID\s*-?\d+/PID/g for @expected;
+@expected = sort @expected;
+is_deeply \@out, \@expected, 'callback worked' or diag explain @out;
+
diff --git a/Parallel-ForkManager-1.17/t/03-callback-data.t b/Parallel-ForkManager-1.17/t/03-callback-data.t
new file mode 100644 (file)
index 0000000..fc567ff
--- /dev/null
@@ -0,0 +1,29 @@
+use strict;
+use warnings;
+
+use Test::More 0.94 tests => 2;
+use File::Temp qw(tempdir);
+
+diag 'This test can take 2-6 seconds, please wait. Started at ' . localtime;
+
+
+my @expected = do { open my $fh, '<', 't/callback_data.txt'; <$fh> };
+@expected = sort @expected;
+
+
+subtest direct => sub {
+       my @out = sort qx{$^X -Ilib examples/callback_data.pl};
+       is_deeply \@out, \@expected, 'callback_data worked' or diag explain @out;
+};
+
+subtest tempdir => sub {
+       my $dir = tempdir( CLEANUP => 1 );
+       my $tempdir = "$dir/abc";
+       mkdir $tempdir;
+       my @out = sort qx{$^X -Ilib examples/callback_data.pl $tempdir};
+       is_deeply \@out, \@expected, 'callback_data worked' or diag explain @out;
+       ok -d $tempdir, 'tempdir was left there';
+};
+
+
+
diff --git a/Parallel-ForkManager-1.17/t/basic-methods.t b/Parallel-ForkManager-1.17/t/basic-methods.t
new file mode 100644 (file)
index 0000000..ab100d3
--- /dev/null
@@ -0,0 +1,38 @@
+use strict;
+use warnings;
+
+use Test::More tests => 8;
+
+use Parallel::ForkManager;
+
+my $pm = Parallel::ForkManager->new(4);
+
+for(1..3) {
+    $pm->start and next;
+    sleep $_;
+    $pm->finish;
+}
+
+my $nbr = $pm->running_procs;
+my @pids = $pm->running_procs;
+
+is $pm->max_procs => 4, 'max procs is 4';
+
+is $nbr => 3, '3 children';
+
+is scalar(@pids) => 3, '3 children';
+
+# on Windows they'll be negative
+like $_ => qr/^-?\d+$/, "looks like a pid" for @pids;
+
+$pm->wait_for_available_procs(3);
+
+is $pm->running_procs => 1, 'only one process left';
+
+$pm->wait_all_children;
+
+is $pm->running_procs => 0, "all done";
+
+
+
+
diff --git a/Parallel-ForkManager-1.17/t/callback.txt b/Parallel-ForkManager-1.17/t/callback.txt
new file mode 100644 (file)
index 0000000..d7a8a45
--- /dev/null
@@ -0,0 +1,26 @@
+** Bob just got out of the pool with PID 23400 and exit code: 5
+** Bob started, pid: 23400
+** Fred just got out of the pool with PID 23395 and exit code: 0
+** Fred started, pid: 23395
+** Jessica just got out of the pool with PID 23399 and exit code: 4
+** Jessica started, pid: 23399
+** Jim just got out of the pool with PID 23396 and exit code: 1
+** Jim started, pid: 23396
+** Lily just got out of the pool with PID 23397 and exit code: 2
+** Lily started, pid: 23397
+** Steve just got out of the pool with PID 23398 and exit code: 3
+** Steve started, pid: 23398
+Bob, Child 5 is about to get out...
+Everybody is out of the pool!
+Fred, Child 0 is about to get out...
+Jessica, Child 4 is about to get out...
+Jim, Child 1 is about to get out...
+Lily, Child 2 is about to get out...
+Steve, Child 3 is about to get out...
+This is Bob, Child number 5
+This is Fred, Child number 0
+This is Jessica, Child number 4
+This is Jim, Child number 1
+This is Lily, Child number 2
+This is Steve, Child number 3
+Waiting for Children...
diff --git a/Parallel-ForkManager-1.17/t/callback_data.txt b/Parallel-ForkManager-1.17/t/callback_data.txt
new file mode 100644 (file)
index 0000000..ec12c21
--- /dev/null
@@ -0,0 +1,5 @@
+Fred started
+Jim started
+Fred just got out of the pool with exit code: 0 and data: Fred 4
+Jim just got out of the pool with exit code: 1 and data: Jim 3
+Everybody is out of the pool!
diff --git a/Parallel-ForkManager-1.17/t/waitpid-conflict.t b/Parallel-ForkManager-1.17/t/waitpid-conflict.t
new file mode 100644 (file)
index 0000000..dcae56f
--- /dev/null
@@ -0,0 +1,38 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Parallel::ForkManager;
+
+my $pm = Parallel::ForkManager->new(4);
+
+local $SIG{ALRM} = sub {
+    fail "test hanging, forever waiting for child process";
+    exit 1;
+};
+
+for ( 1 ) {
+    $pm->start and next;
+    sleep 2;
+    $pm->finish;
+}
+
+my $pid = waitpid -1, 0;
+
+diag "code outside of P::FM stole $pid";
+
+TODO: {
+    local $TODO = 'MacOS and FreeBDS seem to have issues with this';
+
+    eval {
+        alarm 10;
+        $pm->wait_all_children;
+        pass "wait_all_children terminated";
+    };
+
+    is $pm->running_procs => 0, "all children are accounted for";
+
+}
+
+done_testing;
diff --git a/Parallel-ForkManager-1.17/t/waitpid-waitonechild.t b/Parallel-ForkManager-1.17/t/waitpid-waitonechild.t
new file mode 100644 (file)
index 0000000..a84ea4e
--- /dev/null
@@ -0,0 +1,42 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Warn;
+
+use Parallel::ForkManager;
+
+my $pm = Parallel::ForkManager->new(4);
+
+local $SIG{ALRM} = sub {
+    fail "test hanging, forever waiting for child process";
+    exit 1;
+};
+
+for ( 1 ) {
+    $pm->start and last;
+    sleep 2;
+    $pm->finish;
+}
+
+my $pid = waitpid -1, 0;
+
+diag "code outside of P::FM stole $pid";
+
+TODO: {
+    local $TODO = 'MacOS and FreeBDS seem to have issues with this';
+
+    eval {
+        alarm 10;
+        warning_like {
+            $pm->wait_one_child;
+        } qr/child process '\d+' disappeared. A call to `waitpid` outside of Parallel::ForkManager might have reaped it\./,
+            "got the missing child warning";
+        pass "wait_one_child terminated";
+    };
+
+    is $pm->running_procs => 0, "all children are accounted for";
+
+}
+
+done_testing;
diff --git a/Parallel-ForkManager-1.17/t/waitpid_blocking.t b/Parallel-ForkManager-1.17/t/waitpid_blocking.t
new file mode 100644 (file)
index 0000000..5eabf39
--- /dev/null
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+
+use Test::More tests => 1;
+
+use Parallel::ForkManager;
+
+my $pm = Parallel::ForkManager->new(2);
+
+$pm->set_waitpid_blocking_sleep(5);
+my $start = time;
+
+for(1) {
+    $pm->start and last;
+    sleep 1;
+    $pm->finish;
+}
+
+$pm->wait_one_child;
+
+# if the sleep works correctly, we shouldn't
+# check if the child is gone before 5 seconds
+# in the future
+
+cmp_ok abs( 5 - time + $start ), '<=', 2;
+
+
+
+
+
+
diff --git a/Parallel-ForkManager-1.17/xt/release/pause-permissions.t b/Parallel-ForkManager-1.17/xt/release/pause-permissions.t
new file mode 100644 (file)
index 0000000..e18e9a9
--- /dev/null
@@ -0,0 +1,13 @@
+use strict;
+use warnings;
+
+# this test was generated with Dist::Zilla::Plugin::Test::PAUSE::Permissions 0.002
+
+use Test::More;
+BEGIN {
+    plan skip_all => 'Test::PAUSE::Permissions required for testing pause permissions'
+        if $] < 5.010;
+}
+use Test::PAUSE::Permissions;
+
+all_permissions_ok('yanick');
diff --git a/Parallel-ForkManager-1.17/xt/release/unused-vars.t b/Parallel-ForkManager-1.17/xt/release/unused-vars.t
new file mode 100644 (file)
index 0000000..e601076
--- /dev/null
@@ -0,0 +1,14 @@
+#!perl
+
+use Test::More 0.96 tests => 1;
+eval { require Test::Vars };
+
+SKIP: {
+    skip 1 => 'Test::Vars required for testing for unused vars'
+        if $@;
+    Test::Vars->import;
+
+    subtest 'unused vars' => sub {
+all_vars_ok();
+    };
+};
diff --git a/packaging/libparallel-forkmanager-perl.spec b/packaging/libparallel-forkmanager-perl.spec
new file mode 100644 (file)
index 0000000..1750133
--- /dev/null
@@ -0,0 +1,118 @@
+#
+# spec file for package perl-BSSolv
+#
+# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via http://bugs.opensuse.org/
+#
+
+
+Name:           libparallel-forkmanager-perl
+Version:        1.17
+Release:        1
+Source:         %{name}_%{version}.tar.gz
+BuildRoot:      %{_tmppath}/%{name}-%{version}-build
+
+%if 0%{?mandriva_version}
+# force this version on mandriva
+BuildRequires:  libneon0.26-devel
+%endif
+
+%if 0%{?fedora_version}
+BuildRequires:  db4-devel
+BuildRequires:  perl-devel
+%endif
+%if 0%{?suse_version}
+Requires:       perl
+%if 0%{?suse_version} < 1030
+BuildRequires:  expat
+%else
+BuildRequires:  libexpat-devel
+%endif
+%else
+BuildRequires:  expat-devel
+%endif
+%if 0%{?rhel_version} || 0%{?centos_version}
+BuildRequires:  db4-devel
+%endif
+BuildRequires:  cmake
+BuildRequires:  gcc-c++
+BuildRequires:  perl
+BuildRequires:  rpm-devel
+BuildRequires:  xz-devel
+BuildRequires:  zlib-devel
+#RHEL6 moved ExtUtils::MakeMaker outside the main perl package
+BuildRequires:  perl(ExtUtils::MakeMaker)
+# the testsuite uses the check framework
+BuildRequires:  check-devel
+Summary:        A new approach to package dependency solving
+License:        BSD-3-Clause
+Group:          Development/Libraries/C and C++
+# probably needed for rhel/centos on x86_64
+%if 0%{!?perl_vendorarch}
+%define perl_vendorarch %(eval "`%{__perl} -V:installvendorarch`"; echo $installvendorarch)
+%endif
+
+%description
+Using a Satisfyability Solver to compute package dependencies.
+
+%prep
+%setup -c
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS"
+export CXXFLAGS="$CFLAGS"
+CMAKE_FLAGS=
+%if 0%{?fedora_version} || 0%{?rhel_version} || 0%{?centos_version}
+CMAKE_FLAGS="-DFEDORA=1"
+%endif
+
+%if 0%{?rhel_version} || 0%{?centos_version}
+CFLAGS="$CFLAGS -DUSE_OWN_QSORT"
+%endif
+
+#pushd libsolv
+#cmake   $CMAKE_FLAGS \
+#    -DDISABLE_SHARED=1 \
+#    -DCMAKE_BUILD_TYPE=Release \
+#    -DCMAKE_SKIP_RPATH=1 \
+#    -DENABLE_RPMDB=1 \
+#    -DENABLE_DEBIAN=1 \
+#    -DENABLE_ARCHREPO=1 \
+#    -DENABLE_LZMA_COMPRESSION=1 \
+#    -DMULTI_SEMANTICS=1
+#pushd src ; make ; popd
+#pushd ext ; make ; popd
+#popd
+pushd Parallel-ForkManager-%{version} ; perl Makefile.PL ; make ; popd
+
+%install
+pushd Parallel-ForkManager-%{version} ; make DESTDIR=$RPM_BUILD_ROOT install ; popd
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+
+%dir %{perl_sitelib}/Parallel
+%{perl_sitelib}/Parallel/ForkManager.pm
+/usr/share/man/man3/Parallel::ForkManager.3pm.gz
+%{perl_sitearch}/auto
+%{perl_sitearch}/auto/Parallel
+%{perl_sitearch}/auto/Parallel/ForkManager
+%exclude %{perl_sitearch}/auto/Parallel/ForkManager/.packlist
+%exclude %{perl_archlib}/perllocal.pod
+%changelog
+* Fri Oct 18 2013 mls@suse.de
+- update to libsolv-0.4.0 to get REL_MULTIARCH support
+