Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Implementing signals for Win32 Perl using named pipes

by cdarke (Prior)
on Mar 11, 2008 at 12:57 UTC ( [id://673478]=note: print w/replies, xml ) Need Help??


in reply to Implementing signals for Win32 Perl using named pipes

I don't wish to be a wet blanket on what, to me, seems like a neat idea (but I will anyway).

Using the PID for the name of a pipe could give a race condition: rare, but possible. Senario:
1. Process A wants to send a signal to Process B, so opens the pipe.(CreateFile).
2. Process B ends.
3. Process C starts with the same PID as Process B. PIDs can get reused at once on Windows.
4. Process A sends the signal, but to C instead of B.

A "linger" mechanism is required, or maybe some other identifier to be passed down the pipe? At least the process can detect if the pipe already exists before creating it, but the possibility of a race still exists in the period between Process A getting the PID and actually sending the signal.

There are also issues to be thought through with threads, particularly considering the implementation of fork. Using a TID rather than a PID may resolve them, and make the race condition less likely, but still not impossible. Update: What would be really good is an implementation of waitid() with siginfo_t fully supported.
  • Comment on Re: Implementing signals for Win32 Perl using named pipes

Replies are listed 'Best First'.
Re^2: Implementing signals for Win32 Perl using named pipes
by BrowserUk (Patriarch) on Mar 11, 2008 at 13:50 UTC
    PIDs can get reused at once on Windows.

    Really? On my system I cannot get a pid to be reused with anything less that 2632 intervening process starts. Indeed, it is always 2632 intervening starts on my system, which maybe indicative of some flaw in my test method. But still, I think the quoted statement is suspect also?

    #! perl -slw use strict; my %pids; for ( 1 .. 2**16 ) { print my $p = open my $cmd, "cmd /c echo $_ |"; 1 while <$cmd>; close $cmd; exists $pids{ $p } and die sprintf "Duplicate $p after %d process starts", keys % +pids; $pids{ $p }++; } __END__ Duplicate 3904 after 2632 process starts at C:\test\junk11.pl line 10.
    Using a TID rather than a PID may resolve them, and make the race condition less likely, but still not impossible.

    Thread ids are simple incrementing numbers starting from 1 in each process, and would be more (very) likely to be repeated.

    I'm not at all certain that there is a potential race condition. If the process with the pid creates its own named pipe, then when the process terminates for any reason, that named pipe will cease to exist before the process is finally cleared from memory. The system won't allow that to happen until all open handles have been destroyed. And it won't allow the reuse of a pid until the old process has been properly cleaned from the internal tables.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      That you get these symptoms with PIDs are probably a feature of the way perl is doing things, rather than Windows. PIDs and TIDs are created in the same way by kernel (they are just different flavours of the same thing).

      The pipe will only be destroyed when the last handle is closed. If another process has a handle open then the pipe will not be destroyed when the server dies. However, this does raise a simple solution to my race condition. If the client opens a handle to the server process before opening the pipe then it effectively creates a zombie, so the pid cannot be reused. Obviously tidying these handles will be important.
Re^2: Implementing signals for Win32 Perl using named pipes
by Corion (Patriarch) on Mar 11, 2008 at 13:19 UTC

    I don't see that race condition as too critical because the same can happen everywhere where PIDs are recycled too soon. If we find out that PIDs get recycled far too quickly, we can think of a solution then. :)

    A pipe cannot exist at process startup (by mechanism), because every process creates \\.\pipe\Perl\$$ and $$ is unique per process. The fork() emulation and signals between fork()ed children will be interesting to solve under this umbrella, but signals beween forked children could be handled by using shared memory anyway. I'm not sure how unique the fork-child-PIDs are across process boundaries, so maybe using $$ would still work, even with the fork emulation.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://673478]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2024-04-19 05:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found