| File: | blib/lib/App/FileSync/Platform.pm |
| Coverage: | 100.0% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package App::FileSync::Platform; | |||||
| 2 | ||||||
| 3 | # Deliberately dependency-free, and loaded first by every module that uses | |||||
| 4 | # Sub::Private: the end-of-scope hook implementation has to be chosen before | |||||
| 5 | # anything loads B::Hooks::EndOfScope, and Sub::Private loads it at compile time. | |||||
| 6 | ||||||
| 7 | 328 328 328 | 731 244 4255 | use strict; | |||
| 8 | 328 328 328 | 463 247 5930 | use warnings; | |||
| 9 | ||||||
| 10 | 328 328 328 | 49558 251682 792 | use version; our $VERSION = version->declare('0.001.1'); | |||
| 11 | ||||||
| 12 | =encoding utf8 | |||||
| 13 | ||||||
| 14 - 73 | =head1 NAME
App::FileSync::Platform - choose platform workarounds before other modules load
=head1 SYNOPSIS
use App::FileSync::Platform; # first, before Sub::Private or Log::Abstraction
=head1 DESCRIPTION
B::Hooks::EndOfScope 0.28 releases its XS scope hook with an access violation
(0xC0000005) on Perl 5.42 for Windows, after a command has done its work but
before the interpreter exits, so a run that synced everything would still exit
nonzero. Its plain-Perl hook does not fault. The implementation is fixed when
B::Hooks::EndOfScope first loads, so this module makes the choice in a BEGIN
block and is the first thing every App::FileSync module loads.
=head1 FUNCTIONS
=head2 wants_plain_end_of_scope_hook
Purpose: decide whether an interpreter needs the plain-Perl end-of-scope hook.
Args: C<$os> (as C<$^O>), C<$version> (as C<$]>).
Returns: 1 for MSWin32 with a 5.42.x interpreter, otherwise 0.
Side Effects: none.
Usage:
App::FileSync::Platform::wants_plain_end_of_scope_hook('MSWin32', 5.042003); # 1
=head3 EXAMPLE
print App::FileSync::Platform::wants_plain_end_of_scope_hook($^O, $]) ? "PP\n" : "XS\n";
=head3 API SPECIFICATION
=head4 INPUT
[
{ name => 'os', type => 'string', optional => 1 },
{ name => 'version', type => 'string', optional => 1 },
]
=head4 OUTPUT
{ type => 'integer', min => 0, max => 1 }
=head3 MESSAGES
None.
=head3 FORMAL SPECIFICATION
wants : OS Ã VERSION â ð¹
wants(os, v) â os = MSWin32 â§ v â â â§ 5.042 ⤠v < 5.043
=cut | |||||
| 74 | ||||||
| 75 | sub wants_plain_end_of_scope_hook { | |||||
| 76 | 338 | 12807308 | my ($os, $version) = @_; | |||
| 77 | ||||||
| 78 | # 5.42.x only: later releases may not share the fault, and forcing an | |||||
| 79 | # implementation a later B::Hooks::EndOfScope no longer ships would refuse | |||||
| 80 | # to load. | |||||
| 81 | 338 | 1592 | return (defined $os && $os eq 'MSWin32' | |||
| 82 | && defined $version && $version =~ /\A[0-9.]+\z/ | |||||
| 83 | && $version >= 5.042 && $version < 5.043) ? 1 : 0; | |||||
| 84 | } | |||||
| 85 | ||||||
| 86 - 132 | =head2 use_plain_end_of_scope_hook
Purpose: select the plain-Perl hook for an interpreter that needs it.
Args: C<$os>, C<$version>, as for L</wants_plain_end_of_scope_hook>.
Returns: 1 when the environment variable was set, 0 when it was left alone.
Side Effects: may set C<$ENV{B_HOOKS_ENDOFSCOPE_IMPLEMENTATION}> to C<PP>. An
implementation already named in the environment always wins.
Usage:
App::FileSync::Platform::use_plain_end_of_scope_hook($^O, $]);
=head3 EXAMPLE
local $ENV{B_HOOKS_ENDOFSCOPE_IMPLEMENTATION};
App::FileSync::Platform::use_plain_end_of_scope_hook('MSWin32', 5.042003);
print "$ENV{B_HOOKS_ENDOFSCOPE_IMPLEMENTATION}\n"; # PP
=head3 API SPECIFICATION
=head4 INPUT
[
{ name => 'os', type => 'string', optional => 1 },
{ name => 'version', type => 'string', optional => 1 },
]
=head4 OUTPUT
{ type => 'integer', min => 0, max => 1 }
=head3 MESSAGES
None.
=head3 FORMAL SPECIFICATION
ÎENV
os? : OS ; v? : VERSION ; r! : ð¹
r! â B_HOOKS â dom ENV â§ wants(os?, v?)
r! â ENV' = ENV â {B_HOOKS ⦠PP}
¬r! â ENV' = ENV
=cut | |||||
| 133 | ||||||
| 134 | sub use_plain_end_of_scope_hook { | |||||
| 135 | 330 | 146085 | my ($os, $version) = @_; | |||
| 136 | ||||||
| 137 | my $set = (!defined $ENV{B_HOOKS_ENDOFSCOPE_IMPLEMENTATION} | |||||
| 138 | 330 | 987 | && wants_plain_end_of_scope_hook($os, $version)) ? 1 : 0; | |||
| 139 | 330 | 467 | $ENV{B_HOOKS_ENDOFSCOPE_IMPLEMENTATION} = 'PP' if $set; | |||
| 140 | ||||||
| 141 | 330 | 3468 | return $set; | |||
| 142 | } | |||||
| 143 | ||||||
| 144 | BEGIN { | |||||
| 145 | 328 | 41837 | use_plain_end_of_scope_hook($^O, $]); | |||
| 146 | } | |||||
| 147 | ||||||
| 148 | 1; | |||||
| 149 | ||||||