This is well spotted! If I modify my example to include this extra <>:
while(<>) {
print;
}
my $line = <>;
print "END\n";
then only
perl stdin.pl stdin.pl
waits for more input, while the other two versions finished immediately. That is still strange...
UPDATE: I guess Perl will do unshift(@ARGV, '-') unless @ARGV; (copied from LanX above) and "re-open" STDIN because @ARGV was exhausted in the while loop already. When using pipes or redirections this logic will not be applied and <> will only return EOF or similar.