http://www.perlmonks.org?node_id=929097

syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

The demo:
use warnings; #use Inline C => Config => # BUILD_NOISY => 1; use Inline C => <<'EOC'; static int x = 5; void set_x(int z) { x = z; } void get_x(char * id) { printf("%s %d\n", id, x); } EOC get_x('1st call:'); if($pid = fork()) { waitpid($pid,0); } else { set_x(10); get_x('2nd call:'); exit(0); } get_x('3rd call:');
On linux that script fulfils my expectations and outputs:
1st call: 5 2nd call: 10 3rd call: 5
But on Win32, I get:
1st call: 5 2nd call: 10 3rd call: 10
The basic requirement is that the script forks; the child then alters the value of an XS global and exits; that global then still retains its original value.

What options are there that will bring Windows into line with Linux ?
Is there anything that can be done within the C code ?
Perhaps something regarding the way (when/how) the C component is loaded ?

It seems that system() produces a genuine fork, and (as desired) any setting of the global inside a system call is lost when the system call exits.
This is not so straightforward to demo with the Inline::C script, but in the real world scenario I'm dealing with an XS module - and using system instead of fork is one alternative.

But I'm keen to hear what, if any, other options exist - especially any that leave the fork() in place.

Interestingly enough, there's no such problem with *perl* globals. The following script works fine on both Win32 and linux:
use warnings; $g = 5; print "1st call: $g\n"; if($pid = fork()) { waitpid($pid,0); } else { $g = 10; print "2nd call: $g\n"; exit(0); } print "3rd call: $g\n";
It yields (as expected and desired):
1st call: 5 2nd call: 10 3rd call: 5
Cheers,
Rob