Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.85k stars 527 forks source link

perl 5.005_03 core dumps -- singal interrupt related #1005

Closed p5pRT closed 20 years ago

p5pRT commented 24 years ago

Migrated from rt.perl.org#1955 (status was 'resolved')

Searchable as RT1955$

p5pRT commented 24 years ago

From bleh@nut.dhs.org

Perl core dumps shortly after I send an interrupt signal to my program.

Output from gdb​:

[bleh@​nut src]$ gdb perl core GNU gdb 4.18 Copyright 1998 Free Software Foundation\, Inc. GDB is free software\, covered by the GNU General Public License\, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (no debugging symbols found)...

warning​: core file may not match specified executable file. Core was generated by `perl ./psftp-core ssh​://bleh@​localhost/'. Program terminated with signal 11\, Segmentation fault. Reading symbols from /lib/libnsl.so.1...done. Reading symbols from /lib/libdl.so.2...done. Reading symbols from /lib/libm.so.6...done. Reading symbols from /lib/libc.so.6...done. Reading symbols from /lib/libcrypt.so.1...done. Reading symbols from /lib/ld-linux.so.2...done. #0 chunk_alloc (ar_ptr=0x4013d040\, nb=16) at malloc.c​:2804 2804 malloc.c​: No such file or directory. (gdb) bt #0 chunk_alloc (ar_ptr=0x4013d040\, nb=16) at malloc.c​:2804 #1 0x400a840a in __libc_malloc (bytes=4) at malloc.c​:2643 #2 0x807a465 in Perl_safemalloc () #3 0x8088aea in Perl_sv_grow () #4 0x808b271 in Perl_newSV () #5 0x8098e8e in Perl_pp_split () #6 0x80b155d in Perl_runops_standard () #7 0x8059308 in perl_run () #8 0x805787f in main () #9 0x400681eb in __libc_start_main (main=0x8057810 \

\, argc=3\,   argv=0xbffffc34\, init=0x8056b2c \<_init>\, fini=0x80b15cc \<_fini>\,   rtld_fini=0x4000a610 \<_dl_fini>\, stack_end=0xbffffc2c)   at ../sysdeps/generic/libc-start.c​:90 (gdb)

The core occurs when I send an interrupt while the program (attached below) is in ssh_interface. It doesn't occur immeadietly\, but shortly therafter.

psftp.pl

#!/usr/bin/perl

#use Term​::ReadLine; #use Term​::ReadKey; #use IPC​::Open2; use Getopt​::Std; use URI​::URL; #use strict;

# Configuration

# Location of helper programs (we assume its in path at the moment) my $ssh = "psftp-ssh"; my $scp = "psftp-scp"; my $iprompt = "psftp​:"; my $pager = "less"; my $hdir = undef; my $DEBUG = 1; # End configuration

my $version = "0.05"; #my $term = new Term​::ReadLine; my $state = 0; my $user = undef; my $pass = undef; my $host = undef; my $port = undef; my $connected = 0; my $pwd = undef; my $prompt = ""; my $auth_mode = undef; local *RFP;

# help related stuff my @​commands = (); my %help_hash = ();

my %optctl = (); getopts('hu​:c​:'\,\%optctl); if ( $optctl{"h"} ) {   print "$0 $version\n";   print "by Nadeem Riaz (nads\@​bleh.org)\n";   print "Usage $0 [-u user] [-c conf_dir] [host|url]\n";   exit; } $user = $optctl{"u"}; if ( defined($optctl{"c"}) && -d $optctl{"c"} ) {   $hdir = $optctl{"c"}; } else {   $hdir = "$ENV{HOME}/.psftp"; } if ( ! -d $hdir ) {   mkdir($hdir\,0700); } unlink("$hdir/pass"); $SIG{"INT"} = \&do_exit; load_help();

#print "Term Type​: " . $term->ReadLine() . "\n" if ( $DEBUG ); #sub test_func { open(FP\,">log.1"); print FP "I was here\n"; close(FP) }; my ($key\,$val); #$my $attrib = $term->Attribs(); # $attrib->{"filename_quote_characters"} = "\\"; # $attrib->{"filename_quoting_function"} = \&test_func; # $attrib->{"pre_input_hook"} = \&test_func; # $attrib->{"display_match_list"} = \&test_func; # $attrib->{"filename_completion_function"} = \&test_func; # $attrib->{"char_is_quoted_p"} = "\\";

#$attrib->{"completion_word"} = [ sort(@​commands) ]; #$attrib->{"completion_append_character"} = "\""; #$attrib->{"attempted_completion_function"} = \&do_pick_completion; #$attrib->{"filename_quoting_function"} = sub { print "HEY\n" }; #$attrib->{"filename_dequoting_function"} = sub { print "HEY\n" }; #$attrib->{"filename_quote_characters"} = "b"; #$attrib->{"completer_word_break_characters"} = "\'`\@​\$>\<=;|&{( "; #$attrib->{"completion_entry_function"} = undef;

# my $features = $term->Features(); #while ( ($key\,$val) = each ( %{$attrib}) ) { # print "$key = $val\n"; #} #print $term->list_completion_function() . "\n"; if ( @​ARGV > 0 ) {
  open_host($ARGV[0]);
}

my $INT; main_loop();

sub main_loop {   while ( 1 ) {   $prompt = "$iprompt $pwd> ";   my ($line\,$cmd);   print "RIGHT BEFORE NEW TERM!\n";   print "prompt> ";   $line = \; # $line = $term->readline($prompt);   print "RIGHT AFTER NEW TERM!\n";
  my ($cmd\,$line) = split(/\s+/\,$line\,2);   $cmd = lc($cmd);   if ( $cmd eq "lpwd" ) {   system("pwd");   } elsif ($cmd eq "lcd" ) {   do_local_cd($line);   } elsif ($cmd eq "lls" || $cmd eq "ldir" ) {   do_local_ls($line);   } elsif ( $cmd eq "plls" || $cmd eq "pldir" ) {   do_local_paged_ls($line);   } elsif ( $cmd eq "lmkdir" ) {   do_local_mkdir($line);   } elsif ( $cmd eq "lrmdir" || $cmd eq "lrm" || $cmd eq "ldel" ) {   do_local_rm($line);   } elsif ( $cmd eq "lchown" ) {   do_local_chown($line);   } elsif ( $cmd eq "lchmod" ) {   do_local_chmod($line);   } elsif ( $cmd eq "put" ) {   do_put($line);   } elsif ( $cmd eq "mput" ) {   do_mput($line)   } elsif ( $cmd eq "get" ) {   do_get($line);   } elsif ( $cmd eq "mget" ) {   do_mget($line);   } elsif ($cmd eq "cd" ) {   do_remote_cd($line);   } elsif ( $cmd eq "pwd" ) {   do_remote_pwd();   } elsif ( $cmd eq "ls" || $cmd eq "dir" ) {   do_remote_ls($line);   } elsif ( $cmd eq "ls" || $cmd eq "dir" ) {   do_remote_paged_ls($line);   } elsif ( $cmd eq "mkdir" ) {   do_remote_mkdir($line);   } elsif ( $cmd eq "rmdir" || $cmd eq "rm" || $cmd eq "del" ) {   do_remote_rm($line);   } elsif ( $cmd eq "chown" ) {   do_remote_chown($line);   } elsif ( $cmd eq "chmod" ) {   do_remote_chmod($line);
  } elsif( $cmd eq "open" ) {   open_host($line);
  } elsif ( $cmd eq "close" ) {   close_host();
  } elsif ( $cmd eq "clear" ) {   system("clear"); # have to replace this later
  } elsif ( $cmd eq "help" ) {   do_help($line);   } elsif ( $cmd eq "set" ) {   do_set();   } elsif ($cmd eq "save" ) {   do_save();   } elsif ( $cmd eq "exit" || $cmd eq "quit" ) {   do_exit();   } elsif ( $cmd eq "") {   next;   } else {   print "Bad command​: $cmd\n";   }   print "END PF LONG AS ELS/IF\n";   }   exit; }

sub open_host {
  my $line = shift @​_;   $host = undef;   $user = undef;   $pass = undef;   $port = undef;   $auth_mode = undef;   $pwd = "";
  if ( defined($line) ) {   if ( $line =~ /^ssh\​:\/\//i ) {   my $url = new URI​::URL $line;   $host = $url->host;   $port = $url->port;   $user = $url->user;   $pass = $url->password;   } else {   $host = $line;   }   }   if ( ! defined($host) || $host eq "" ) {   print "Enter host name​: ";   chomp($host = \);   }   if ( ! defined($user) || $user eq "" ) {   print "Enter user name​: ";   chomp($user = \);   }   print "Connecting to $host....\n";   ($auth_mode\,$pwd) = get_auth_mode() if ( ! defined($auth_mode) || $auth_mode eq "" );   if ( ! defined($auth_mode) ) {   print "Couldn't connect to $host\n";   unlink("$hdir/pass");   return 0;   }   print "connected!\n";   $connected = 1;   print "Connection successful to $host\, auth_mode = $auth_mode\n" if ( $DEBUG );   $pwd = remote_cd("") if ( ! defined($pwd) || $pwd eq "" ); }

sub close_host {   if ( ! $connected ) {   print "Not connected\n";   return;   }   $connected =0;   $host = undef;   $user = undef;   $pass = undef;   $port = undef;   $auth_mode = undef;   $pwd = "";   unlink("$hdir/pass"); }

sub get_auth_mode {
  my $c = "$ssh $host \"echo no pass ; pwd\" 2>&1";   my $oldint = $SIG{'INT'};   $SIG{'INT'} = \&ssh_interrupt;
  open(RFP\,"$c |") || die "Couldn't create pipe​: $!";   sleep(1);
 
  my (@​lo\,$line);   eval {
  $SIG{"ALRM"} = sub {   print "Timeout on auth mode!\n";   if ( ! defined($pass) || $pass eq "") {   print "Enter password​: ";   $pass = \;   chomp($pass);   # ReadMode 4;   # my $key = "";   #while ($key ne "\n" ) {   # $key = ReadKey(1);   # $pass .= $key;   #}   #chomp($pass);   #ReadMode 0;   #print "\n";   }   write_pass($pass);   $SIG{"ALRM"} = sub { print "Connection to $host timed out\n"; die "Couldn't connect to $host" };   alarm 30;   };
  alarm(5);   $line = \;   alarm 0;   sleep(1);   @​lo = \;   };
  if ( $@​ ) {   return undef;   }  
  alarm 0;   close(RFP) if ( *RFP );   $SIG{"INT"} = $oldint;   my ($gpwd\,$auth);   if ( $line =~ /Bad host name/i ) {   print "Bad host name\n";   return (undef\,undef);   } elsif ($line =~ /password/i ) {
  my $o = shift @​lo;   if ( $o =~ /Permission denied/ ) {   print "Permission denied\n";   return (undef\,undef);   } elsif ( $o !~ /no pass/ ) {   print "INTERNAL ERROR!​: $o \n";   return (undef\,undef);   }   $auth = "password";   } elsif ( $line =~ /no pass/i ) {   $auth = "RSARhost";   } else {   print "ERROR Couldn't determine authentication mode\n";   return (undef\,undef);;   }   $gpwd = shift(@​lo);   chomp($gpwd);   return ($auth\,$gpwd); }

sub write_pass {   my $pass = shift @​_;   local *pFP;   open(pFP\,">$hdir/pass") || die "Couldn't open pass file!\n$!\n";   print pFP "$pass\n";   close(pFP); }

sub remote_cd {   my $dir = shift @​_;
  my $c = "cd $dir 2>&1; pwd";   my @​cd_output = execute_remote_cmd($c);   my $cdo = $cd_output[0];   chomp($cdo);   if ( $cdo =~ /No such file or directory/ ) {   return (undef\,"No such file or directory");   } elsif ($cdo =~ /Not a directory/ ) {   return (undef\,"Not a directory");   } elsif ( $cdo =~ /Permission denied/ ) {   return(undef\,"Permission deinied");   } elsif ( ! defined($cdo) ) {   return (undef\,"Internal Error");
  }   return $cdo;
}

sub execute_remote_cmd {   my ($cmd\,$print) = (@​_);   my $c = "$ssh $host \"cd $pwd ; $cmd\" 2>&1";   return ssh_interface($c\,$print); }

sub ssh_interface {   my ($c\,$print) = (@​_);
  print "-- begin ssh interface --\n" if ( $DEBUG ); # open2(\*RFP\,\*WFP\,$c) || die "Couldn't create pipe​: $!";   print "current int = $SIG{'INT'}\n";   my $oldint = $SIG{'INT'};   print "old int = $oldint\n";   $SIG{'INT'} = \&ssh_interrupt;   print "new int = $SIG{'INT'}\n";   open(RFP\,"$c |");   sleep(1);   if ( $auth_mode eq "password" ) { # write_pass($pass); # print WFP "$pass\n";   \;   }   sleep(1);   my @​output;   if ( $print ) {   my $c;
  $| =1; # Flush after every print   while ( read(RFP\,$c\,1) ) {   print $c;   }   $| = 0;   } else {   @​output = \;   }   print("-- end ssh interface --\n") if ( $DEBUG );   if ( $INT ) {
  $INT = 0;   return 0;   }   close(RFP);   print "CLOSE SUCCESFUL\n";   $SIG{'INT'} = $oldint;   if ( $print ) {   return 1;   } else {   return @​output;   } }

sub do_remote_cd {
  if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $dir = shift @​_;   my @​cd_output = remote_cd($dir);   if ( defined($cd_output[0]) ) {   $pwd = $cd_output[0];   } else {   print "$cd_output[1]\n";
  } }

sub do_remote_mkdir {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $dir = shift @​_;   execute_remote_cmd("mkdir $dir"\,1);
}

sub do_remote_rm {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $files = shift @​_;   execute_remote_cmd("rm -rf $files"\,1);
}

sub do_remote_chown {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $files = shift @​_;   execute_remote_cmd("chown $files"\,1); }

sub do_remote_chmod {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $files = shift @​_;   execute_remote_cmd("chmod $files"\,1); }

sub do_remote_pwd {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   print "$pwd\n"; }

sub do_remote_ls {
  if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $args = shift @​_;   execute_remote_cmd("ls $args"\,1);   print "REMOTE LS RETURN SUCCESSFUL\n"; }

sub do_remote_paged_ls {
  if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   local *lFP;   my $args = shift @​_;   my @​lines = execute_remote_cmd("ls $args");   if ( ! open(lFP\,"| $pager") ) {   print "Couldnt pipe to pager!\n";   return;   }   my $line;   foreach $line (@​lines) {   print lFP $line;   }
}

sub do_local_cd {   my $dir = shift @​_;   if ( ! chdir("$dir") ) {   print "Couldn't change to dir $dir​: $!\n";   return undef;   }   return 1; }

sub do_local_ls {   my $line = shift @​_;   system("ls $line"); }

sub do_local_paged_ls {   my $line = shift @​_;   system("ls $line | $pager"); }

sub do_local_mkdir {   my $dir = shift @​_;   if ( ! mkdir("$dir"\,0700) ) {   print "Couldn't make local dir $dir​: $!\n";   return undef;   }   return 1; }

sub do_local_rm {   my $files = shift @​_;   system("rm -rf $files"); }

sub do_local_chown {   my $files = shift @​_;   system("chown $files"); }

sub do_local_chmod {   my $files = shift @​_;   system("chmod $files"); }

sub do_put {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $line = shift @​_;
  if ( ! defined($line) || $line eq "" ) {   print "No file given!\n";   return 0;   }  
  # Break up args\, and assign them to appropriate var   my ($arg\,$file\,$remote\,@​jun) = split_args($line);   my $options = "";   if ( $arg eq "-r" || $arg eq "-R" ) {   $options = "-r";   } else {   $remote = $file;   $file = $arg;   }  
  # Check file|dir exist   if ( $options ) {   if ( ! -d $file && ! -f $file ) {   print "'$file' is not a file or directory (does it exist?)\n";   return 0;   }
  } else {   if ( ! -f $file ) {   print "'$file' is not a normal file\n";   return 0;   }   }

  put_files([ $file ]\,$remote\,$options);   return; }

sub do_mput {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $line = shift @​_;
  if ( ! defined($line) || $line eq "" ) {   print "No file given!\n";   return 0;   }  
  # Break up args\, and assign them to appropriate var   my (@​files) = split_args($line);   my $options = "";   my $arg = shift(@​files);   if ( $arg eq "-r" || $arg eq "-R" ) {   $options = "-r";   } else {   unshift(@​files\,$arg);   }  
  if (@​files \< 1 ) {   print "No files given!\n";   return 0;   }  
  my ($file\,@​put_list);   foreach $file (@​files) {   next if ( $file eq "" );   print "Trying $file\n" if ( $DEBUG );   my $print_glob_errors = 1;   if ( $options ) {   if ( -d $file || -f $file ) {   push(@​put_list\,$file);   $print_glob_errors = 0;   }   } else {   if ( -f $file ) {   push(@​put_list\,$file);   $print_glob_errors = 0;   }   }
  my ($glob\,@​glob_list);   @​glob_list = glob($file);
  glob_for​: foreach $glob (@​glob_list) {   print "\tglob'd​: $glob\n" if ( $DEBUG );   my $p;   foreach $p (@​put_list) {   next glob_for if ( $p eq $glob );   }   # Check file|dir exist   if ( $options ) {   if ( ! -d $glob && ! -f $glob ) {   print "'$glob' is not a file or directory (does it exist?)\n" if ( $print_glob_errors );   next;   }
  } else {   if ( ! -f $glob ) {   print "'$glob' is not a normal file\n" if ( $print_glob_errors );   next;   }   }   push(@​put_list\,$glob)
  }   }   put_files(\@​put_list\,undef\,$options);   return 1; }

sub put_files {   my ($local\,$remote\,$options) = (@​_);   print "put_file​: options = $options Trying to put @​{$local} as $remote\n" if ( $DEBUG );   my $c = "$scp -a -Q ";   if ( defined($options) && $options ne "") {   $c .= " $options ";   }  
  my @​local = @​{$local};   my $x;   for ($x=0;$x\<@​local;$x++) {   $local[$x] = shell_escape($local[$x]);   }  
  $remote = shell_escape($remote);   my $f = "$pwd/$remote";
  if ( $remote =~ /^\// ) {   $f = $remote;   }   ssh_interface("$c @​local $user\@​$host​:$f 2>&1"\,1); }

sub do_get {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   my $file = shift @​_;
  if ( ! defined($file) || $file eq "" ) {   print "No file given!\n";   return 0;   }   my ($args\,$nf) = split(/\s+/\,$file\,2);   my $options = "";   if ( defined($nf) && $nf ne "" && ($args eq "-r" || $args eq "-R") ){   $options = "-r";   $file = $nf;   }   get_file($file\,undef\,$options);
  return; }

sub do_mget {   if ( ! $connected ) {   print "Not connected to host!\n";   return;   }   print "Feature not done yet\n";   return; }

sub get_file {   my ($remote\,$local\,$options) = (@​_);   print "get_file​: options = $options Trying to get $remote as $local\n" if ( $DEBUG );   my $c = "$scp -a -Q ";   if ( defined($options) && $options ne "") {   $c .= " $options ";   }   $local = shell_escape($local);   $remote = shell_escape($remote);   if ( $local eq "" ) { $local = "./"; }   my $f = "$pwd/$remote";   if ( $remote =~ /^\// ) {   $f = $remote;   }   ssh_interface("$c $user\@​$host​:$f $local 2>&1"\,1); }

sub do_help {   if ( @​commands \< 1 ) {   load_help();   }   my $cmd = shift @​_;   if ( defined($cmd) && $cmd ne "" ) {
  if ( exists $help_hash{$cmd} ) {   print "$cmd​: $help_hash{$cmd}";   } else {   print "There is no help avaible for $cmd\n";   }   } else {   my @​sc = sort(@​commands);   my ($x\,$y\,$sc);   for ($x=0;$x\<5;$x++) {   for ($y=0;$y\<6;$y++) {   $sc->[$x]->[$y] = $sc[($x*6)+$y];   }   }   print "Commands available​:\n"; # print "commands​: @​sc\n" if ( $DEBUG );   for ($x=0;$x\<6;$x++) {   print "$sc->[0]->[$x]\t\t$sc->[1]->[$x]\t\t$sc->[2]->[$x]\t\t$sc->[3]->[$x]\t\t$sc->[4]->[$x]\n";   }
  } }

sub load_help {   @​commands = qw(lpwd lcd lls plls lmkdir lrm lchown lchmod put mput get mget cd pwd ls pls mkdir rm rmdir chown chmod open close clear exit help set save);   $help_hash{"lpwd"} = "display local parent directory\nUsage​: lpwd\n";   $help_hash{"lcd"} = "change local directory\nUsage​: lcd \

\n";   $help_hash{"lls"} = "display list of file on local machine\nUsage​: lls [dir]\n";   $help_hash{"plls"} = "displays list of files on local machine\, paged with program given by pager variable\nUsage​: plls [dir]\n";   $help_hash{"lmkdir"} = "create a directory on local machine\nUsage​: lmkdir \\n";   $help_hash{"lrm"} = "delete files or directories on local machine\nUsage​: lrm \<file|dir>\n";   $help_hash{"lchown"} = "change ownership of file on local machine\nUsage​: lchown \\n";   $help_hash{"lchmod"} = "change mode of file on local machine\nUsage​: lchmod \\n";   $help_hash{"put"} = "uploads a file or dir to the remote machine\nUsage​: put [-r] \<file|dir> \<name of file|dir on remote machine>\n";   $help_hash{"mput"} = "uploads files and/or dirs to the remote machine\nUsage​: mput [-r] \<file list|dir list|globs|any mix thereof>\n";   $help_hash{"get"} = "No help avaible on this yet\n";   $help_hash{"mget"} = "No help avaible on this yet\n";   $help_hash{"pwd"} = "display local parent directory\nUsage​: pwd\n";   $help_hash{"cd"} = "change local directory\nUsage​: cd \\n";   $help_hash{"ls"} = "display list of file on remote machine\nUsage​: ls [dir]\n";   $help_hash{"pls"} = "displays list of files on remote machine\, paged with program given by pager variable\nUsage​: pls [dir]\n";   $help_hash{"mkdir"} = "create a directory on remote machine\nUsage​: mkdir \\n";   $help_hash{"rm"} = "delete files or directories on remote machine\nUsage​: rm \<file|dir>\n";   $help_hash{"rmdir"} = $help_hash{"rm"};   $help_hash{"chown"} = "change ownership of file on remote machine\nUsage​: chown \\n";   $help_hash{"chmod"} = "change mode of file on remote machine\nUsage​: chmod \\n";   $help_hash{"open"} = "opens a connection to a host\nUsage​: open [host|url]\n";   $help_hash{"close"} = "close current connection\nUsage​: close\n";   $help_hash{"help"} = "displays commands avaible or help on a command\nUsage​: help [command]";   $help_hash{"exit"} = "exits program\nUsage​: exit\n";   $help_hash{"set"} = "displays all variables\, request var\, or sets vars depending on arguments\nUsage​: set [var] [new value]\n";   $help_hash{"save"} = "saves current variable values to local config file\nUsage​: save\n"; }

sub do_exit {   if ( $connected ) {   close_host();   }   #ReadMode 0;   unlink("$hdir/pass");
  # On interrupts ReadLine might mangle the term\, thus we   # call reset to fix us up   system("reset -Q");   exit;
}

sub ssh_interrupt {   $INT = 1;   $SIG{"INT"} = \&do_exit;   print "SSH INTERRUPT\n" if ( $DEBUG );   close(RFP);   return 1; }

sub do_set {   print "Feature not done yet\n";   return 0; }

sub do_save {   print "Feature not done yet\n";   return 0; }

sub shell_escape {   my $line = shift @​_;   $line =~ s/\"/\\"/g;   $line =~ s/\'/\\'/g;   $line =~ s/\s/\\ /g;   $line =~ s/\!/\\!/g;
  $line =~ s/\[/\\[/g;   $line =~ s/\]/\\]/g;   $line =~ s/\(/\\(/g;   $line =~ s/\)/\\)/g;   return $line }

#sub do_pick_completion { # my ($text\, $line\, $start\, $end) = @​_; # if (substr($line\, 0\, $start) =~ /^\s*$/) { # return $term->completion_matches($text\,$attrib->{list_completion_function}); # } else { # my ($cmd\,$rline) = split(/\s+/\,$line); # $cmd = lc($cmd); # if ( ($cmd =~ /^l/ && $cmd ne "ls") || $cmd eq "plls" || $cmd eq "put" || $cmd eq "mput") { # # Local file completion # my @​list = $term->completion_matches($text\,$attrib->{filename_completion_function}); # $state++; # my $x; # for ($x=0;$x\<@​list;$x++) { # $list[$x] = shell_escape($list[$x]); # } # open(FP\,">log.1"); # print FP "urmfg​: $state​: @​list\n"; # close(FP); # return (@​list); # } else {
# $attrib->{"inhibit_completion"} = 1; # return (); # } #
# } #}

sub split_args {   my $text = shift @​_;   my ($space\,$escape\,$open_quote);   my ($warg\,@​args);   my ($x);  
  # Split line into args
  for($x=0;$x\<length($text);$x++) {   if ( substr($text\,$x\,1) eq "\\" ) {   if ( $escape ) {   $warg .= "\\";   } else {   $escape = 1;   next;   }   } elsif ( !$escape && substr($text\,$x\,1) eq "\"" ) {   if ( $open_quote ) {   # New Arg   push(@​args\,$warg);   $warg ="";   $open_quote = 0;   } else {   $open_quote = 1;   }   next;   } elsif ( ! $escape && ! $open_quote && substr($text\,$x\,1) eq " " ) {   if ( ! $space ) {   # New Arg   push(@​args\,$warg);   $warg ="";
  $space = 1;   }   next;   }   if ( $space ) {   $space = 0;
  } elsif ( $escape ) {   $escape = 0;   }   $warg .= substr($text\,$x\,1);   }   push(@​args\,$warg);   my $y;   for ($y=0;$y\<@​args;$y++) {   print "$y. '$args[$y]'\n" if ( $DEBUG );   }   return (@​args); }

# END PSFTP.pl

Perl Info ``` Site configuration information for perl 5.00503: Configured by root at Mon Aug 30 23:08:56 EDT 1999. Summary of my perl5 (5.0 patchlevel 5 subversion 3) configuration: Platform: osname=linux, osvers=2.2.5-22smp, archname=i386-linux uname='linux porky.devel.redhat.com 2.2.5-22smp #1 smp wed jun 2 09:11:51 edt 1999 i686 unknown ' hint=recommended, useposix=true, d_sigaction=define usethreads=undef useperlio=undef d_sfio=undef Compiler: cc='cc', optimize='-O2', gccversion=egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) cppflags='-Dbool=char -DHAS_BOOL -I/usr/local/include' ccflags ='-Dbool=char -DHAS_BOOL -I/usr/local/include' stdchar='char', d_stdstdio=undef, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 alignbytes=4, usemymalloc=n, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldl -lm -lc -lposix -lcrypt libc=, so=so, useshrplib=false, libperl=libperl.a Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl 5.00503: /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005 . Environment for perl 5.00503: HOME=/home/bleh LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/local/bin:/bin:/usr/bin::/usr/X11R6/bin:/sbin:/usr/sbin:/usr/local/java/jdk/bin:/home/bleh/usr/bin:/home/bleh/work/code/cli PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

\nads@&#8203;bleh\.org writes​:

This is a bug report for perl from nads@​bleh.org\, generated with the help of perlbug 1.26 running under perl 5.00503.

----------------------------------------------------------------- [Please enter your report here]

Perl core dumps shortly after I send an interrupt signal to my program.

Signals can do that to any perl. Only the most trivial of signal handlers are safe. They must not allocate any memory at all (very hard to be sure of in perl code) as the signal may have occured in the memory allocator and that is probably not re-entrant.

There are various approaches to making signals usable which may be in the development track.

Both Tk and the Event modules have 'synchronous' signals implemented at the C level\, but delayed until the next "event despatch" occurs.

#0 chunk_alloc (ar_ptr=0x4013d040\, nb=16) at malloc.c​:2804 2804 malloc.c​: No such file or directory. (gdb) bt #0 chunk_alloc (ar_ptr=0x4013d040\, nb=16) at malloc.c​:2804 #1 0x400a840a in __libc_malloc (bytes=4) at malloc.c​:2643

Pretty typical ...

$SIG{"INT"} = \&do_exit; sub do_exit { if ( $connected ) { close_host(); } #ReadMode 0; unlink("$hdir/pass");
# On interrupts ReadLine might mangle the term\, thus we # call reset to fix us up system("reset -Q"); exit;
}

Far\, far too complex.

-- Nick Ing-Simmons

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Nick Ing-Simmons writes​:

Perl core dumps shortly after I send an interrupt signal to my program.

Signals can do that to any perl. Only the most trivial of signal handlers are safe.

This is wrong. No signal handlers are safe.

Hope this helps (why should I repeat it again and again?)\, Ilya

P.S.

There are various approaches to making signals usable which may be in the development track.

I wonder why not we add something like

  $SIG{CHLD} = [inc => \$counter\, set => [\$foo\, 13]\, pid => \$pid];

and avoid all the problems with a Perl function call altogether...

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : I wonder why not we add something like : : $SIG{CHLD} = [inc => \$counter\, set => [\$foo\, 13]\, pid => \$pid]; : : and avoid all the problems with a Perl function call altogether...

Bletch\, in a vague sort of way.

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Larry Wall writes​:

Ilya Zakharevich writes​: : I wonder why not we add something like : : $SIG{CHLD} = [inc => \$counter\, set => [\$foo\, 13]\, pid => \$pid]; : : and avoid all the problems with a Perl function call altogether...

Bletch\, in a vague sort of way.

But comparing to what we have now it would be a paradise. ;-)

Ilya

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : Larry Wall writes​: : > : > Ilya Zakharevich writes​: : > : I wonder why not we add something like : > : : > : $SIG{CHLD} = [inc => \$counter\, set => [\$foo\, 13]\, pid => \$pid]; : > : : > : and avoid all the problems with a Perl function call altogether... : > : > Bletch\, in a vague sort of way. : : But comparing to what we have now it would be a paradise. ;-)

I was bletching the interface\, not the implementation. I agree that the implementation of the current interface could use improvement. This has all been discussed before. We need to delay sub invocations until we know we're in a safe state\, such as the beginning of a statement\, or at the interator of any looping constructs\, including regular expressions. Of course\, within regular expressions we'd have to take extra care to be re-entrant\, but the swash routines already do that now--see Perl_save_re_context().

An interesting question is where to install the checks in the regular expression engine such that we do not suffer significant overhead\, while at the same time guaranteeing that the evaluation will progress to a check point in reasonable time\, say\, less than a second or so. Possibly the right time to check is at the longest failure of a * or +\, just before we start backing off. Possibly we should just check on every backoff\, if accessing the global "signal_pending" variable is cheap.

In this scheme\, here's our C signal handler​:

  Signal_t   Perl_sighandler(int sig)   {   PL_signal_count[sig]++;   PL_signal_pending++;   }

Seems pretty safe to me.

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Mon\, Jan 10\, 2000 at 01​:28​:16PM -0800\, Larry Wall wrote​:

Ilya Zakharevich writes​: : Larry Wall writes​: : > : > Ilya Zakharevich writes​: : > : I wonder why not we add something like : > : : > : $SIG{CHLD} = [inc => \$counter\, set => [\$foo\, 13]\, pid => \$pid]; : > : : > : and avoid all the problems with a Perl function call altogether... : > : > Bletch\, in a vague sort of way. : : But comparing to what we have now it would be a paradise. ;-)

I was bletching the interface\, not the implementation. I agree that the implementation of the current interface could use improvement.

And I was saying that a change of the interface can make the improvements to become improvements\, not changes with some positive and some negative effects.

This has all been discussed before. We need to delay sub invocations until we know we're in a safe state\, such as the beginning of a statement\, or at the interator of any looping constructs\, including regular expressions.

No\, we do not *need* to delay sub invocations. Delaying the invocation is one of the possible workarounds to the current disaster. It has many negative effects\, like being a NOP in the case of a long-running opcode.

And if you want the delayed semantic\, you may do

$SIG{CHLD} = [delayed => sub {...} ];

And you can do

$SIG{CHLD} = [delayed => sub {...}\, repeated => [2\, sub {...}] ];

which might mean that if another signal appears when one is delayed (meaning​: AHA\, something dangerous happens​: signal was not served\, probably a long-running opcode\, we need some recovery action)\, another sub (or maybe another %SIG-compatible specification\, as at the start) should be run.

Of course\, within regular expressions we'd have to take extra care to be re-entrant\, but the swash routines already do that now--see Perl_save_re_context().

Which is an obvious bletch.

Ilya

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : > This has all been discussed before. We need to delay sub invocations : > until we know we're in a safe state\, such as the beginning of a : > statement\, or at the interator of any looping constructs\, including : > regular expressions. : : No\, we do not *need* to delay sub invocations. Delaying the : invocation is one of the possible workarounds to the current : disaster. It has many negative effects\, like being a NOP in the case : of a long-running opcode.

And in what way does your proposal help this? What interrupts the long running opcode in your version of reality? You modified some existing variables\, so what?

: And if you want the delayed semantic\, you may do : : $SIG{CHLD} = [delayed => sub {...} ]; : : And you can do : : $SIG{CHLD} = [delayed => sub {...}\, repeated => [2\, sub {...}] ]; : : which might mean that if another signal appears when one is delayed : (meaning​: AHA\, something dangerous happens​: signal was not served\, : probably a long-running opcode\, we need some recovery action)\, another : sub (or maybe another %SIG-compatible specification\, as at the start) : should be run.

That's more needless complexity. This should be hidden from the user. Immediate dispatch on duplicate signals could be done in the current scheme as well without exposing it to the poor user. And that's only necessary if we aren't smart enough to find all the proper check points\, which I think we are.

: > Of course\, within regular expressions we'd have : > to take extra care to be re-entrant\, but the swash routines already do : > that now--see Perl_save_re_context(). : : Which is an obvious bletch.

But then you're talking implementation again. I'd rather see the complexity in the implementation than in the interface. Perl was intended to be easy to use\, not necessarily easy to implement. Of course\, for a given interface\, a simpler implementation is nice\, but that's not what we're optimizing for.

And the whole idea of signals is so busted anyway that I don't think a complex interface is worth it. Save the TMTOWTDI for more important stuff.

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Mon\, Jan 10\, 2000 at 03​:54​:56PM -0800\, Larry Wall wrote​:

Ilya Zakharevich writes​: : > This has all been discussed before. We need to delay sub invocations : > until we know we're in a safe state\, such as the beginning of a : > statement\, or at the interator of any looping constructs\, including : > regular expressions. : : No\, we do not *need* to delay sub invocations. Delaying the : invocation is one of the possible workarounds to the current : disaster. It has many negative effects\, like being a NOP in the case : of a long-running opcode.

And in what way does your proposal help this? What interrupts the long running opcode in your version of reality?

The kernel\, of course.

You modified some existing variables\, so what?

Modification of existing variables is the smallest problem of Perl signal handlers. All the real damage is done during the subroutine call frame. And using the proposed interface you do not need the subroutine call. Moreover\, you may insure that the changes you do from the signal handler are atomic (say\, by croaking if an atomic change is not possible).

: And you can do : : $SIG{CHLD} = [delayed => sub {...}\, repeated => [2\, sub {...}] ]; : : which might mean that if another signal appears when one is delayed : (meaning​: AHA\, something dangerous happens​: signal was not served\, : probably a long-running opcode\, we need some recovery action)\, another : sub (or maybe another %SIG-compatible specification\, as at the start) : should be run.

That's more needless complexity. This should be hidden from the user. Immediate dispatch on duplicate signals could be done in the current scheme as well without exposing it to the poor user.

Yes\, it may be done. However\, it is done *dangerously*\, why in my scheme it may be done safely.

And if you do not like the interface\, write a module which deparses

sub { ++$count; return }

to [ inc => \$count ]. Make assignment to $SIG autoload this module. If deparse fails\, enable the delayed samantic.

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Ilya Zakharevich (lists.p5p)​:

And if you do not like the interface\, write a module which deparses

sub { ++$count; return }

to [ inc => \$count ]. Make assignment to $SIG autoload this module. If deparse fails\, enable the delayed samantic.

I hate to suggest this\, but wouldn't   $SIG{FOO} = sub { ++$count; return } be easier for all concerned?

The even-numbered elements to your anon array there (not even a hash. furrfu.) appear to be forming a `sub-language' - inc\, set\, and so on. This seems wasteful​:   If you disallow running arbitary code\, you're restricting people.   If you allow\, say\, a `[code => sub { ... }]'\, everyone will use that instead of the other `instructions'\, out of laziness.

Either way\, you lose. Blech\, in fact.

-- Generic Fortune.

p5pRT commented 24 years ago

From @samtregar

On 11 Jan 2000\, Simon Cozens wrote​:

I hate to suggest this\, but wouldn't $SIG{FOO} = sub { ++$count; return } be easier for all concerned?

The even-numbered elements to your anon array there (not even a hash. furrfu.) appear to be forming a `sub-language' - inc\, set\, and so on. This seems wasteful​: If you disallow running arbitary code\, you're restricting people. If you allow\, say\, a `[code => sub { ... }]'\, everyone will use that instead of the other `instructions'\, out of laziness.

True\, but currently a sub {} cannot be executed by a signal handler in a safe manner. If a signal arrives at a critical moment\, such as inside malloc or some other non-reentrent system call\, then even calling a simple sub {} is not garaunteed to be safe. Ilya's "sub-language" is one proposal to solve this problem - presumably some XSUB would be cooked up to parse the defined sublanguage and take action when recieving signals.

-sam

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Mon\, 10 Jan 2000 13​:28​:16 -0800 (PST)   Larry Wall \larry@&#8203;wall\.org wrote   in \200001102128\.NAA15919@&#8203;kiev\.wall\.org​:

:We need to delay sub invocations until we know we're in a safe state\, :such as the beginning of a statement\, or at the interator of any looping :constructs\, including regular expressions.

What about slow-running ops? It seems like some of them require more careful work than others. For example\, sort() on a large data set can take a swell spell\, and readline() on a serial line or stream connection can take virtually infinite time. In the latter case\, I suppose we have the EINTR and the SA_RESTART dodge. Here's my list of such operators​:

  sys related​: accept\, close\, connect\, fcntl\, flock\, getc\, ioctl\,   open\, print\, read\, readline\, recv\, send\, syscall\,   sysread\, syswrite\, wait\, waitpid

Those aren't that bad. It's the others that seem more challenging. For example​:

  indirect calls​: sort\, map\, grep

Where do those take the signal? What if it's a built-in sorting\, such as C\<sort @​array>\, or using the newly optimized built-ins (from perldelta​: ``Simple sort() using { $a \<=> $b } and the like are optimized Many common sort() operations using a simple inlined block are now optimized for faster performance.'')?

What about system() and `backticks`? Are these part of the sys-related case above? Is glob() an issue? It uses many readdir()s\, unless it's not built-in\, in which case it will be using an external program. Does this fall into the system() and `backtick` case?

Is sleep() a sys-related case?

What about list-context flipflops? "a" .. "zzzzz" takes a long time (well\, until you hit out of memory :-).

How about the dofile and require operators? Is it safe to permit receipt of the signal once they've compiled and once they're executing their newly compiled code? I assume that the import() component of the use operator would be signallable during its execution.

Finally\, let's have some fun ones. What about tie() and its related intercepts? There's no reason to imagine that any of the TIE*() functions shall complete in "reasonable" (non-arbitrary) time. At what granularity should they be interruptible? Consider​:

  tie %mib\, 'Tie​::SMTP'\, $remhost;   $desc = $mib{ "system.sysDescr" };

The tie itself might take a long time because $remhost is unreachable. If there's underlying Perl code that's stuck in one of the previously mentioned cases (e.g. connect)\, perhaps this suffices. Same situation with the tied()d call to FETCH() in the next line.

But what if it's in XS code? How will reliable signal delivery interact with XS code?

--tom

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Larry> That's more needless complexity.
Larry> This should be hidden from the user.

Ilya> And if you do not like the interface\, write a module which Ilya> deparses Ilya> sub { ++$count; return } Ilya> to [ inc => \$count ]. Make assignment to $SIG autoload this module. Ilya> If deparse fails\, enable the delayed semantic.

This still falls under the imprecation against `needless complexity'.

Upon packing his bags in preparation for a journey\, the savvy traveller discards fully fifty percent of his stowed possessions\, for he realizes that needless clutter and gratuitous baggage but weigh him down and distract him from his goal. It is only after many years of repeated mistakes that the truly seasoned traveller can a priori recognize unjustifiable bloat for its hidden promise of inevitable annoyance.

--tom

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

For example\, sort() on a large data set can take a swell spell

Sort is a good example. I remember an IBM rep doing a demo of a little APL "portable" machine back in the early 70s which I immediately hung by typing in the magic apl gibberish for​: "sort" "reverse" "0..50000"

It went away\, and could not be interrupted. He finally had to power cycle it rather than wait for the sort to finish (it was\, obviously\, not a speed demon - I'm not entirely sure\, but it may have been a 4004 chip running a 360 emulator running 360 apl :-).

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

At 06​:59 AM 1/11/00 -0700\, Tom Christiansen wrote​:

On Mon\, 10 Jan 2000 13​:28​:16 -0800 (PST) Larry Wall \larry@&#8203;wall\.org wrote in \200001102128\.NAA15919@&#8203;kiev\.wall\.org​:

​:We need to delay sub invocations until we know we're in a safe state\, ​:such as the beginning of a statement\, or at the interator of any looping ​:constructs\, including regular expressions.

What about slow-running ops? It seems like some of them require more careful work than others.

What we'd need was a wedge into the long-running op at a safe place. Basically the same code that'd get executed between ops (probably the exact same code) just done within an op.

We could do this either with an explicit wedge (essentially a yield()) which feels icky\, or with an implicit wedge\, say in one of the SV manipulating functions. We might want to have an explicit "interrupts enable" flag so that the default is to not do this--dunno if it'd be safe to drop into runops() in the middle of a regex for example.

That still gets us nowhere with potentially long running system calls\, unless there's some way to issue them asynchronously and explicitly wait for their return\, in which case we could treat it as a general event wait and catch it the same way as we'd catch signals or other async events.

But what if it's in XS code? How will reliable signal delivery interact with XS code?

Well\, the wedge method would get us in for anything that didn't block\, but that may not be enough\, and it may not be safe to be dropping into runops from within an XS function anyway. Nobody writes these to be reentrant-safe. (Though the number of cases where it actually matters is relatively small)

  Dan

--------------------------------------"it's like this"------------------- Dan Sugalski even samurai dan@​sidhe.org have teddy bears and even   teddy bears get drunk

p5pRT commented 24 years ago

From @TimToady

Tom Christiansen writes​: : On Mon\, 10 Jan 2000 13​:28​:16 -0800 (PST) : Larry Wall \larry@&#8203;wall\.org wrote : in \200001102128\.NAA15919@&#8203;kiev\.wall\.org​: : : :We need to delay sub invocations until we know we're in a safe state\, : :such as the beginning of a statement\, or at the interator of any looping : :constructs\, including regular expressions. : : What about slow-running ops? It seems like some of them require more : careful work than others. For example\, sort() on a large data set can : take a swell spell\, and readline() on a serial line or stream connection : can take virtually infinite time. In the latter case\, I suppose we have : the EINTR and the SA_RESTART dodge. Here's my list of such operators​: : : sys related​: accept\, close\, connect\, fcntl\, flock\, getc\, ioctl\, : open\, print\, read\, readline\, recv\, send\, syscall\, : sysread\, syswrite\, wait\, waitpid : : Those aren't that bad. It's the others that seem more challenging. : For example​: : : indirect calls​: sort\, map\, grep

That's why I said\, "at the iterator [un-sic] of any looping constructs." I was counting those as looping constructs.

: Where do those take the signal? What if it's a built-in sorting\, such as : C\<sort @​array>\, or using the newly optimized built-ins (from perldelta​: : ``Simple sort() using { $a \<=> $b } and the like are optimized Many : common sort() operations using a simple inlined block are now optimized : for faster performance.'')?

The proper check point is probably in qsortsv()\, which is used to call all the other routines.

: What about system() and `backticks`? Are these part of the sys-related : case above? Is glob() an issue? It uses many readdir()s\, unless it's not : built-in\, in which case it will be using an external program. Does this : fall into the system() and `backtick` case?

Any op of that sort can set a flag which says it's safe to call the sub directly\, as we do now.

: Is sleep() a sys-related case?

Can be solved with either as above or via EINTR.

: What about list-context flipflops? "a" .. "zzzzz" takes a long time : (well\, until you hit out of memory :-).

"at the iterator of any looping constructs"

: How about the dofile and require operators? Is it safe to permit : receipt of the signal once they've compiled and once they're executing : their newly compiled code? I assume that the import() component of : the use operator would be signallable during its execution.

The iterator of the compiler is byacc.

: Finally\, let's have some fun ones. What about tie() and its related : intercepts? There's no reason to imagine that any of the TIE*() functions : shall complete in "reasonable" (non-arbitrary) time. At what granularity : should they be interruptible? Consider​: : : tie %mib\, 'Tie​::SMTP'\, $remhost; : $desc = $mib{ "system.sysDescr" }; : : The tie itself might take a long time because $remhost is unreachable. : If there's underlying Perl code that's stuck in one of the previously : mentioned cases (e.g. connect)\, perhaps this suffices. Same situation : with the tied()d call to FETCH() in the next line.

If it's tied to Perl code\, that operates at the granularity of the Perl code\, as normal. A connect would be an EINTR or "sig_sub_is_safe = 1" situation.

: But what if it's in XS code? How will reliable signal delivery interact : with XS code?

Existing XS code is a problem regardless. Inventing a new minilanguage does not solve this. We have the choice (or perhaps the user has the choice) of whether frequent hanging or occasional core dumping is the lesser of two evils. But there are at least three ways to ameliorate this.

First\, we can do the deliver-immediately-on-duplicate-signal trick. That could be generalized to deliver immediately on any second signal if sufficient time has passed\, provided time() is a safe system call.

Second\, we could interrupt ourselves periodically with an interval timer on systems that support that\, and deliver any sufficiently delayed signals immediately.

Third\, we could document how to install a check point\, deal with EINTR\, set sig_sub_is_safe\, etc. for the benefit of XS writers\, in the expectation that they'll do the right thing.

As far as I'm concerned\, the main remaining issue is how to direct signals to a particular thread. This seems to me to be an issue of the check point code simply refusing to deliver a signal unless the right thread is running (and of course making sure the signal thread gets scheduled as soon as is reasonable). We might not be able to honor sig_sub_is_safe under threaded code\, but then all your blocking operations should send you back to the scheduler anyway\, so it doesn't seem to be a big issue.

In short\, this is all insane\, but it's the sort of insanity we should be protecting the Perl programmer from.

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

:As far as I'm concerned\, the main remaining issue is how to direct :signals to a particular thread.

I never did manage to get signal delivery working under Linux\, which used pids for threads.

:In short\, this is all insane\, but it's the sort of insanity we should :be protecting the Perl programmer from.

sigs :-)

--tom

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

At 11​:37 AM 1/11/00 -0700\, Tom Christiansen wrote​:

​:As far as I'm concerned\, the main remaining issue is how to direct ​:signals to a particular thread.

I never did manage to get signal delivery working under Linux\, which used pids for threads.

Signals and threads are going to be a persistent problem. It's anyone's guess which thread gets an async signal\, and even the sync signals that ought to go to the thread that generated them often don't. (The POSIX standard says they don't have to\, IIRC)

Then Linux adds more fun to the mix\, as it's only mostly POSIX-compliant\, and signals that ought to go to any thread instead only go to the thread that triggered the signal in the first place. Very annoying if you're using a single signal-handling thread. (Of course\, if you stop assuming LinuxThreads are POSIX compliant it's a lot easier\, since the POSIX assumptions don't get in the way. Pity they used the POSIX routine names\, which is just darned confusing)

  Dan

--------------------------------------"it's like this"------------------- Dan Sugalski even samurai dan@​sidhe.org have teddy bears and even   teddy bears get drunk

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 10​:31​:36AM -0800\, Larry Wall wrote​:

Existing XS code is a problem regardless. Inventing a new minilanguage does not solve this.

Of course immediate atomic delivery solves this\, as well as removes the complexity of intentional slowing-down of tight loops.

First\, we can do the deliver-immediately-on-duplicate-signal trick. That could be generalized to deliver immediately on any second signal if sufficient time has passed\, provided time() is a safe system call.

If this delivery is unsafe\, then this is just putting things under the carpet.

As far as I'm concerned\, the main remaining issue is how to direct signals to a particular thread.

Let me repeat one of the reference points​: close to impossible under OS/2.

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Simon Cozens writes​:

And if you do not like the interface\, write a module which deparses

sub { ++$count; return }

to [ inc => \$count ]. Make assignment to $SIG autoload this module. If deparse fails\, enable the delayed samantic.

I hate to suggest this\, but wouldn't $SIG{FOO} = sub { ++$count; return } be easier for all concerned?

Hmm\, is not this what I proposed?

This seems wasteful​: If you disallow running arbitary code\, you're restricting people.

You cannot run arbitrary code in an immediate sighandler. If you delay execution\, you are restricting people.

If you allow\, say\, a \`\[code => sub \{ \.\.\. \}\]'\, everyone will use that

instead of the other `instructions'\, out of laziness.

Their lazyness is nothing of our concern.

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Tom Christiansen writes​:

Larry> That's more needless complexity.
Larry> This should be hidden from the user.

Ilya> And if you do not like the interface\, write a module which Ilya> deparses Ilya> sub { ++$count; return } Ilya> to [ inc => \$count ]. Make assignment to $SIG autoload this module. Ilya> If deparse fails\, enable the delayed semantic.

This still falls under the imprecation against `needless complexity'.

"This" is what? Needless for what?

Upon packing his bags in preparation for a journey\, the savvy traveller discards fully fifty percent of his stowed possessions\, for he realizes that needless clutter and gratuitous baggage but weigh him down and distract him from his goal. It is only after many years of repeated mistakes that the truly seasoned traveller can a priori recognize unjustifiable bloat for its hidden promise of inevitable annoyance.

Hmm\, is not it prose? Did anybody find any technical contents in this?

Ilya

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : On Tue\, Jan 11\, 2000 at 10​:31​:36AM -0800\, Larry Wall wrote​: : > Existing XS code is a problem regardless. Inventing a new minilanguage : > does not solve this. : : Of course immediate atomic delivery solves this\, as well as removes : the complexity of intentional slowing-down of tight loops.

But your delivery doesn't deliver\, in the sense of guaranteeing the script will notice the signal any time soon. My scheme is also does atomic delivery\, only not to Perl\, but to a C array and a global\, which we then take pains to check periodically.

: > First\, we can do the deliver-immediately-on-duplicate-signal trick. : > That could be generalized to deliver immediately on any second signal if : > sufficient time has passed\, provided time() is a safe system call. : : If this delivery is unsafe\, then this is just putting things under the carpet.

As I recall\, you're the one who proposed immediate delivery on a second signal not so very many messages ago.

: > As far as I'm concerned\, the main remaining issue is how to direct : > signals to a particular thread. : : Let me repeat one of the reference points​: close to impossible under OS/2.

Let me point out that we don't have to deliver C level signals to another thread. We only have to deliver Perl level signals. My proposal divorces the two. The C signal comes in on whatever thread happens to be running at the time\, and atomically sets up the Perl signal. Then all other Perl threads simply ignore the signal until the signal thread wakes up. At worst this depends on the latency of the scheduler\, and remains completely safe.

Larry

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : Simon Cozens writes​: : > >And if you do not like the interface\, write a module which : > >deparses : > > : > > sub { ++$count; return } : > > : > >to [ inc => \$count ]. Make assignment to $SIG autoload this module. : > >If deparse fails\, enable the delayed samantic. : > : > I hate to suggest this\, but wouldn't : > $SIG{FOO} = sub { ++$count; return } : > be easier for all concerned? : : Hmm\, is not this what I proposed?

Yes\, and it's still relatively useless in the overall scheme of things. The purpose of a signal is to force the scheduler to run some meaningful code. Just because C prevents this doesn't mean we can't fake it in Perl.

: > This seems wasteful​: : > If you disallow running arbitary code\, you're restricting people. : : You cannot run arbitrary code in an immediate sighandler. If you : delay execution\, you are restricting people.

We can make that restriction relatively insignificant.

: > If you allow\, say\, a `[code => sub { ... }]'\, everyone will use that : > instead of the other `instructions'\, out of laziness. : : Their lazyness is nothing of our concern.

You mean\, their laziness is nothing of *your* concern. It is certainly my concern. That's just one of the things a language designer has to take into account.

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 01​:03​:04PM -0800\, Larry Wall wrote​:

: > Existing XS code is a problem regardless. Inventing a new minilanguage : > does not solve this. : : Of course immediate atomic delivery solves this\, as well as removes : the complexity of intentional slowing-down of tight loops.

But your delivery doesn't deliver\, in the sense of guaranteeing the script will notice the signal any time soon. My scheme is also does atomic delivery\, only not to Perl\, but to a C array and a global\, which we then take pains to check periodically.

It is good that our schemes are so close. But mine is better ;-)​: you do not need to check things periodically.

First I failed to see how your scheme will make script notice the signal. Later I realized that you probably you mean die() here​:

  $SIG{} = [die => $message];

will die atomically\, but may leave things in a non-consistent state. This is indeed a questionable behaviour. What are other things people want to do in a sighandler?

  a) set a variable;   b) increment a variable;   c) exit();   d) wait() and assign the result;   e) wait() and append the result to an array/hash;   f) die with a message;

All things in a)..d) can be made atomically without any damage. e) can be done atomically if the array/hash is tied to something which allows an atomic update. This leaves 'f'\, which is much better in your setup.

So question is​: are we going to make a major rewrite just to allow really-safe die() in a signal handler?

: Let me repeat one of the reference points​: close to impossible under OS/2.

Let me point out that we don't have to deliver C level signals to another thread. We only have to deliver Perl level signals.

Not a tiny bit easier​: you still need to unblock the thread.

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 01​:11​:11PM -0800\, Larry Wall wrote​:

: Their lazyness is nothing of our concern.

You mean\, their laziness is nothing of *your* concern. It is certainly my concern. That's just one of the things a language designer has to take into account.

Hmm\, is it the reason why now *by default* h2xs produces almost unusable code? [Well\, *now* it does not produce anything\, I meant the state things may boil down to.] ;-)

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Ilya Zakharevich wrote​:

Simon Cozens writes​:

    If you allow\, say\, a \`\[code => sub \{ \.\.\. \}\]'\, everyone will use that

instead of the other `instructions'\, out of laziness.

Their lazyness is nothing of our concern.

hm\, and I thought laziness was one of the three great vitues of a programmer. maybe that was something I read in the Python manual...

maybe I'm being hubristic.

Greg

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 04​:35​:27PM -0500\, london@​pixelmagic.com wrote​:

Their lazyness is nothing of our concern.

hm\, and I thought laziness was one of the three great vitues of a programmer.

It is a virtue of a programmer\, but not in *another* programmer. ;-)

An attempt to grant lazyness to signal-handler's programmers is laudable in general. But if the price is significant obfuscation of the code base\, slowing things down\, and unusability in present of XSUBs\, things start to look very different.

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

At 04​:19 PM 1/11/00 -0500\, Ilya Zakharevich wrote​:

This is indeed a questionable behaviour. What are other things people want to do in a sighandler?

a) set a variable; b) increment a variable; c) exit(); d) wait() and assign the result; e) wait() and append the result to an array/hash; f) die with a message;

g) Queue up another I/O request h) Update a Tk display i) Send a syslog message j) Close one file on a filehandle and open another

You're letting the crippled signal implementation limit you.

: Let me repeat one of the reference points​: close to impossible under OS/2.

Let me point out that we don't have to deliver C level signals to another thread. We only have to deliver Perl level signals.

Not a tiny bit easier​: you still need to unblock the thread.

So? Unless the thread is waiting on a blocking system call it's not a big deal. The thread's cond_waiting and you signal it.

  Dan

--------------------------------------"it's like this"------------------- Dan Sugalski even samurai dan@​sidhe.org have teddy bears and even   teddy bears get drunk

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 04​:32​:46PM -0500\, Dan Sugalski wrote​:

At 04​:19 PM 1/11/00 -0500\, Ilya Zakharevich wrote​:

This is indeed a questionable behaviour. What are other things people want to do in a sighandler?

a) set a variable; b) increment a variable; c) exit(); d) wait() and assign the result; e) wait() and append the result to an array/hash; f) die with a message;

g) Queue up another I/O request h) Update a Tk display i) Send a syslog message j) Close one file on a filehandle and open another

If die() were safe\, all these would easy to implement...

: Let me repeat one of the reference points​: close to impossible under OS/2.

Let me point out that we don't have to deliver C level signals to another thread. We only have to deliver Perl level signals.

Not a tiny bit easier​: you still need to unblock the thread.

So? Unless the thread is waiting on a blocking system call it's not a big deal.

Why do you thing it is not going to be waiting on a blocking system call most of the time? For many threading paradigms this is exactly what happens.

The thread's cond_waiting and you signal it.

What made you thingk cond_wait() is not a blocking system call?

Ilya

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : On Tue\, Jan 11\, 2000 at 01​:03​:04PM -0800\, Larry Wall wrote​: : > : > Existing XS code is a problem regardless. Inventing a new minilanguage : > : > does not solve this. : > : : > : Of course immediate atomic delivery solves this\, as well as removes : > : the complexity of intentional slowing-down of tight loops. : > : > But your delivery doesn't deliver\, in the sense of guaranteeing the : > script will notice the signal any time soon. My scheme is also does : > atomic delivery\, only not to Perl\, but to a C array and a global\, which : > we then take pains to check periodically. : : It is good that our schemes are so close. But mine is better ;-)​: you : do not need to check things periodically.

Only for some values of "you". If you increment a variable then some value of "you" has to write code to check the variable. In my proposal Perl checks it for you.

: First I failed to see how your scheme will make script notice the signal. : Later I realized that you probably you mean die() here​: : : $SIG{} = [die => $message]; : : will die atomically\, but may leave things in a non-consistent state.

Eh? I never said anything like that...

: This is indeed a questionable behaviour. What are other things people : want to do in a sighandler? : : a) set a variable;

Forcing the script to check the variable periodically.

: b) increment a variable;

Forcing the script to check the variable periodically.

: c) exit();

Can be optimized away as a subroutine with a known constant value. :-)

: d) wait() and assign the result;

Again\, somebody's gotta check for the result explicitly if they care.

: e) wait() and append the result to an array/hash; : f) die with a message;

: All things in a)..d) can be made atomically without any damage. e) : can be done atomically if the array/hash is tied to something which : allows an atomic update.

Seems unlikely\, since you probably have to allow malloc in there somewhere to grow the array\, unless you're journaling to disk\, which seems relatively useless\, or allocate a fixed size array\, which can drop signals.

: This leaves 'f'\, which is much better in your setup.

And you left out​:

  g) anything else you might want to do safely in a signal handler.

: So question is​: are we going to make a major rewrite just to allow : really-safe die() in a signal handler?

I don't think it's a major rewrite.

All we have to do is make sure our check points can reach a consistent state if they need to. So the check point in sort may have to switch stacks\, for instance.

: > : Let me repeat one of the reference points​: close to impossible under OS/2. : > : > Let me point out that we don't have to deliver C level signals to : > another thread. We only have to deliver Perl level signals. : : Not a tiny bit easier​: you still need to unblock the thread.

How does OS/2 unblock a thread? Obviously it can\, or threads would never run. How about if the signal-handling thread is waiting on some I/O that another thread can provide?

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 01​:37​:18PM -0800\, Larry Wall wrote​:

: It is good that our schemes are so close. But mine is better ;-)​: you : do not need to check things periodically.

Only for some values of "you". If you increment a variable then some value of "you" has to write code to check the variable. In my proposal Perl checks it for you.

Really? You mean that on

  $SIG{USR1} = sub {$i++; return};

Perl will insert code to check for $i? And what will it do after the check? ;-)

: Later I realized that you probably you mean die() here​: : : $SIG{} = [die => $message]; : : will die atomically\, but may leave things in a non-consistent state.

Eh? I never said anything like that...

Then I fail to see what was your point.

: All things in a)..d) can be made atomically without any damage. e) : can be done atomically if the array/hash is tied to something which : allows an atomic update.

Seems unlikely\, since you probably have to allow malloc in there somewhere to grow the array\, unless you're journaling to disk\, which seems relatively useless\, or allocate a fixed size array\, which can drop signals.

... but can mark that it dropped these signals\, that is almost as good as not dropping them.

: Not a tiny bit easier​: you still need to unblock the thread.

How does OS/2 unblock a thread? Obviously it can\, or threads would never run.

The only way for user to unblock a thread is to kill it.

How about if the signal-handling thread is waiting on some I/O that another thread can provide?

All signals are delivered to thread 0. Make it a signal-handling thread\, and everything becomes nice. 1/2 ;-) But I think signals-via-IO may be possible (if you forget about the overhead). Though it would be much easier to do by mutexen. ;-)

Ilya

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : On Tue\, Jan 11\, 2000 at 01​:11​:11PM -0800\, Larry Wall wrote​: : > : Their lazyness is nothing of our concern. : > : > You mean\, their laziness is nothing of *your* concern. It is certainly : > my concern. That's just one of the things a language designer has to : > take into account. : : Hmm\, is it the reason why now *by default* h2xs produces almost : unusable code? [Well\, *now* it does not produce anything\, I meant the : state things may boil down to.] ;-)

Getting people to write better code is another one of those things that a language designer has to take into account. A program generator that is run once like h2xs doesn't have to meet the same standards of backward compatibility as does the language itself. We can reasonably assume the user is running the version of Perl that h2xs is running\, and doesn't intend to downgrade to a previous version. And if they want to write something backward compatible and put it on CPAN\, then they should be testing against older versions of Perl\, so the older h2xs is presumably available. Or we can provide a --use_vars switch.

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 01​:46​:30PM -0800\, Larry Wall wrote​:

And if they want to write something backward compatible and put it on CPAN\, then they should be testing against older versions of Perl\, so the older h2xs is presumably available. Or we can provide a --use_vars switch.

So much for respect to lazyness.

Ilya

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : On Tue\, Jan 11\, 2000 at 01​:37​:18PM -0800\, Larry Wall wrote​: : > : It is good that our schemes are so close. But mine is better ;-)​: you : > : do not need to check things periodically. : > : > Only for some values of "you". If you increment a variable then some : > value of "you" has to write code to check the variable. In my proposal : > Perl checks it for you. : : Really? You mean that on : : $SIG{USR1} = sub {$i++; return}; : : Perl will insert code to check for $i? And what will it do after the : check? ;-)

No\, it inserts code to check for sig_count[SIGUSR1]\, which will then cause some meaningful code to run\, rather than just an increment.

: > : Later I realized that you probably you mean die() here​: : > : : > : $SIG{} = [die => $message]; : > : : > : will die atomically\, but may leave things in a non-consistent state. : > : > Eh? I never said anything like that... : : Then I fail to see what was your point.

Likewise.

: > : All things in a)..d) can be made atomically without any damage. e) : > : can be done atomically if the array/hash is tied to something which : > : allows an atomic update. : > : > Seems unlikely\, since you probably have to allow malloc in there somewhere : > to grow the array\, unless you're journaling to disk\, which seems relatively : > useless\, or allocate a fixed size array\, which can drop signals. : : ... but can mark that it dropped these signals\, that is almost as good : as not dropping them.

I'd rather just deliver them safely.

: > : Not a tiny bit easier​: you still need to unblock the thread. : > : > How does OS/2 unblock a thread? Obviously it can\, or threads would never : > run. : : The only way for user to unblock a thread is to kill it.

I'll bet there are 18 other ways\, if you're sneaky.

: > How about if the signal-handling thread is waiting on some I/O that : > another thread can provide? : : All signals are delivered to thread 0. Make it a signal-handling : thread\, and everything becomes nice. 1/2 ;-) But I think : signals-via-IO may be possible (if you forget about the overhead). : Though it would be much easier to do by mutexen. ;-)

I'm not worried about the overhead\, since signals are supposed to be relatively rare events.

I should perhaps make clear my assumption that a signal-handling Perl thread would only interested in handling signals. I'm not thinking that a signal-handling thread would also be handling a bunch of other events unless we can find a portable way to multiplex them. That might be a restriction on writing portable threading code in Perl.

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 01​:59​:10PM -0800\, Larry Wall wrote​:

: > : Not a tiny bit easier​: you still need to unblock the thread. : > : > How does OS/2 unblock a thread? Obviously it can\, or threads would never : > run. : : The only way for user to unblock a thread is to kill it.

I'll bet there are 18 other ways\, if you're sneaky.

Try it.

I should perhaps make clear my assumption that a signal-handling Perl thread would only interested in handling signals. I'm not thinking that a signal-handling thread would also be handling a bunch of other events unless we can find a portable way to multiplex them. That might be a restriction on writing portable threading code in Perl.

We *need* an event loop in Perl core - or very close to it. This may be a part of this loop.

Ilya

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : On Tue\, Jan 11\, 2000 at 01​:46​:30PM -0800\, Larry Wall wrote​: : > And if they : > want to write something backward compatible and put it on CPAN\, then : > they should be testing against older versions of Perl\, so the older : > h2xs is presumably available. Or we can provide a --use_vars switch. : : So much for respect to lazyness.

That's your view. The world needs a few people who always see things in black and white.

I respect laziness a great deal. But then\, I respect a lot of other things as well. A language designer cannot afford to grind any ax to the exclusion of all the other axes. A language designer cannot even afford to ignore the people who prefer to grind a particular ax.

Larry

p5pRT commented 24 years ago

From @TimToady

Ilya Zakharevich writes​: : We *need* an event loop in Perl core - or very close to it. This may : be a part of this loop.

Indeed\, that's what the perl-loop mailing list has been working on for lo these many months. Any folks from perl-loop want to comment?

Larry

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

At 04​:33 PM 1/11/00 -0500\, Ilya Zakharevich wrote​:

On Tue\, Jan 11\, 2000 at 04​:32​:46PM -0500\, Dan Sugalski wrote​:

At 04​:19 PM 1/11/00 -0500\, Ilya Zakharevich wrote​:

This is indeed a questionable behaviour. What are other things people want to do in a sighandler?

a) set a variable; b) increment a variable; c) exit(); d) wait() and assign the result; e) wait() and append the result to an array/hash; f) die with a message;

g) Queue up another I/O request h) Update a Tk display i) Send a syslog message j) Close one file on a filehandle and open another

If die() were safe\, all these would easy to implement...

Really? All die needs to do is propagate either a string or an object out to the non-signal code. There's a touch more involved in the things I listed.

There's no reason you shouldn't be able to do just about anything you want in a perl signal handler. I might draw the line at things that jump into the lexer\, but that still seems restrictive.

: Let me repeat one of the reference points​: close to impossible under OS/2.

Let me point out that we don't have to deliver C level signals to another thread. We only have to deliver Perl level signals.

Not a tiny bit easier​: you still need to unblock the thread.

So? Unless the thread is waiting on a blocking system call it's not a big deal.

Why do you thing it is not going to be waiting on a blocking system call most of the time? For many threading paradigms this is exactly what happens.

So we have sync system calls instead spawn off a thread to do the call while the spawning thread cond_waits on something. To wake the thread you kill the thread doing the syscall and pop a cond_signal to the waiting thread. There are other ways\, too\, of course.

The thread's cond_waiting and you signal it.

What made you thingk cond_wait() is not a blocking system call?

What makes you think the cond_wait that I'm thinking of is the one you're thinking of? And what makes you think I'm not considering tracking the condition and signalling it?

  Dan

--------------------------------------"it's like this"------------------- Dan Sugalski even samurai dan@​sidhe.org have teddy bears and even   teddy bears get drunk

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Tom Christiansen writes​:

Larry> That's more needless complexity.
Larry> This should be hidden from the user.

Ilya> And if you do not like the interface\, write a module which Ilya> deparses Ilya> sub { ++$count; return } Ilya> to [ inc => \$count ]. Make assignment to $SIG autoload this module. Ilya> If deparse fails\, enable the delayed semantic.

This still falls under the imprecation against `needless complexity'.

"This" is what? Needless for what?

Needless for making easy things easy. Contributatory toward introducing labyrinthine complexities that are the very thing that have driven so many people away from languages like C.
Let's not slap them in the face with the same crap.

Upon packing his bags in preparation for a journey\, the savvy traveller discards fully fifty percent of his stowed possessions\, for he realizes that needless clutter and gratuitous baggage but weigh him down and distract him from his goal. It is only after many years of repeated mistakes that the truly seasoned traveller can a priori recognize unjustifiable bloat for its hidden promise of inevitable annoyance.

Hmm\, is not it prose? Did anybody find any technical contents in this?

Are you really so completely impervious to the allusions of metaphor and allegory that one must always present to you relentlessly sterile bits and bytes full of machine language of tediously symbolic progamming calculus with which to feed into your presumed wetware? While I realize that you are not a native speaker\, I also truly believe that you would find\, if you gave them a smidgen of a chance\, that even the most remedial of reading-for-comprehension skills hold a utility beyond that of boosting his parents' pride when they read their 3rd grader's report card.

--tom

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Let me repeat one of the reference points​: close to impossible under OS/2.

So what?

--tom

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

for those just joining the list now\, here is a quick recap of this thread of discussion​:

Man​: Is this the right room for an argument? Other Man​:(pause) I've told you once. Man​: No you haven't! Other Man​: Yes I have. M​: When? O​: Just now. M​: No you didn't! O​: Yes I did! M​: You didn't! O​: I did! M​: You didn't! O​: I'm telling you\, I did! M​: You didn't! O​: Oh I'm sorry\, is this a five minute argument\, or the full half hour? M​: Ah! (taking out his wallet and paying) Just the five minutes. O​: Just the five minutes. Thank you. O​: Anyway\, I did. M​: You most certainly did not! O​: Now let's get one thing perfectly clear​: I most definitely told you! M​: Oh no you didn't! O​: Oh yes I did! M​: Oh no you didn't! O​: Oh yes I did! M​: Oh no you didn't! O​: Oh yes I did! M​: Oh no you didn't! O​: Oh yes I did! M​: Oh no you didn't! O​: Oh yes I did! M​: Oh no you didn't! O​: Oh yes I did! M​: No you DIDN'T! O​: Oh yes I did! M​: No you DIDN'T! O​: Oh yes I did! M​: No you DIDN'T! O​: Oh yes I did! M​: Oh look\, this isn't an argument! (pause) O​: Yes it is! M​: No it isn't! (pause) M​: It's just contradiction! O​: No it isn't! M​: It IS! O​: It is NOT! M​: You just contradicted me! O​: No I didn't! M​: You DID! O​: No no no! M​: You did just then! O​: Nonsense! M​: (exasperated) Oh\, this is futile!! (pause) O​: No it isn't! M​: Yes it is! (pause) M​: I came here for a good argument! O​: AH\, no you didn't\, you came here for an argument! M​: An argument isn't just contradiction. O​: Well! it CAN be! M​: No it can't! M​: An argument is a connected series of statement intended to establish a proposition. O​: No it isn't! M​: Yes it is! 'tisn't just contradiction. O​: Look\, if I *argue* with you\, I must take up a contrary position! M​: Yes but it isn't just saying 'no it isn't'. O​: Yes it is! M​: No it isn't! O​: Yes it is! M​: No it isn't! O​: Yes it is! M​: No it ISN'T! Argument is an intellectual process. Contradiction is just the automatic gainsaying of anything the other person says. O​: It is NOT! M​: It is! O​: Not at all! M​: It is! (The Arguer hits a bell on his desk and stops.) O​: Thank you\, that's it. M​: (stunned) What? O​: That's it. Good morning. M​: But I was just getting interested! O​: I'm sorry\, the five minutes is up. M​: That was never five minutes!! O​: I'm afraid it was. M​: (leading on) No it wasn't..... O​: I'm sorry\, I'm not allowed to argue any more. M​: WHAT?? O​: If you want me to go on arguing\, you'll have to pay for another five minutes. M​: But that was never five minutes just now! Oh Come on! Oh this is... This is ridiculous! O​: I told you... I told you\, I'm not allowed to argue unless you PAY! M​: Oh all right. (takes out his wallet and pays again.) There you are. O​: Thank you. M​: (clears throat) Well... O​: Well WHAT? M​: That was never five minutes just now. O​: I told you\, I'm not allowed to argue unless you've paid! M​: Well I just paid! O​: No you didn't! M​: I DID!!! O​: YOU didn't! M​: I DID!!! O​: YOU didn't! M​: I DID!!! O​: YOU didn't! M​: I DID!!! O​: YOU didn't! M​: I-dbct-fd-tq! I don't want to argue about it! O​: Well I'm very sorry but you didn't pay! M​: Ah hah! Well if I didn't pay\, why are you arguing??? Ah HAAAAAAHHH! Gotcha! O​: No you haven't! M​: Yes I have! If you're arguing\, I must have paid. O​: Not necessarily. I *could* be arguing in my spare time. M​: I've had enough of this! O​: No you haven't. (door slam)

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 01​:59​:10PM -0800\, Larry Wall wrote​:

: Really? You mean that on : : $SIG{USR1} = sub {$i++; return}; : : Perl will insert code to check for $i? And what will it do after the : check? ;-)

No\, it inserts code to check for sig_count[SIGUSR1]\, which will then cause some meaningful code to run\, rather than just an increment.

Apparently\, I got carried away by the mantra "do as little as you can in a signal handler". Given "absolutely safe" signals\, one could indeed do all the work inside\, instead of setting a flag to do some processing later\, if needed.

But since safe signals are not possible (see XSUBs)\, and require a significant rewrite of the most important "do a lot" Perl opcodes (at any checkpoint we should be ready for a longjump)\, this is still rather moot.

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 05​:22​:20PM -0500\, Dan Sugalski wrote​:

Why do you thing it is not going to be waiting on a blocking system call most of the time? For many threading paradigms this is exactly what happens.

So we have sync system calls instead spawn off a thread to do the call while the spawning thread cond_waits on something. To wake the thread you kill the thread doing the syscall and pop a cond_signal to the waiting thread. There are other ways\, too\, of course.

You still think that you can wake something which cond_wait()s from another thread. And you make things extremely complicated and extremely unefficient.

What made you thingk cond_wait() is not a blocking system call?

What makes you think the cond_wait that I'm thinking of is the one you're thinking of? And what makes you think I'm not considering tracking the condition and signalling it?

Waking *all* the thread which wait on this?

Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Tue\, Jan 11\, 2000 at 03​:26​:48PM -0700\, Tom Christiansen wrote​:

Ilya> deparses Ilya> sub { ++$count; return } Ilya> to [ inc => \$count ]. Make assignment to $SIG autoload this module. Ilya> If deparse fails\, enable the delayed semantic.

This still falls under the imprecation against `needless complexity'.

"This" is what? Needless for what?

Needless for making easy things easy. Contributatory toward introducing labyrinthine complexities that are the very thing that have driven so many people away from languages like C.
Let's not slap them in the face with the same crap.

We are discussing signals. If you have something to say about this topic\, feel free to do so. [I have no slightest idea what you are trying to say here. Signal handlers in C are infinitely simpler than in Perl​: people can write them.]

Upon packing his bags in preparation for a journey\, the savvy traveller discards fully fifty percent of his stowed possessions\, for he realizes that needless clutter and gratuitous baggage but weigh him down and distract him from his goal. It is only after many years of repeated mistakes that the truly seasoned traveller can a priori recognize unjustifiable bloat for its hidden promise of inevitable annoyance.

Hmm\, is not it prose? Did anybody find any technical contents in this?

Are you really so completely impervious to the allusions of metaphor and allegory that one must always present to you relentlessly sterile bits and bytes full of machine language of tediously symbolic progamming calculus with which to feed into your presumed wetware?

There was some time in my life (aeons ago) when I could have share your surprise. Fortunately\, one of my friends (who happened to be a head of a section of Hermitage) asked me to look through my thesis. "It is prose" (sp?)\, was his verdict.

This episode helped my presumed wetware a lot. You can put Hanukka bush ornaments on anything. Most of the time the only reason Moliere syndrom appears is to hide the fact that the message is content-free. Even if not\, things may improve by removing ornaments.

Hope this helps\, Ilya

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

Hi\,

Larry Wall​:

Ilya Zakharevich writes​: : We *need* an event loop in Perl core - or very close to it. This may : be a part of this loop.

Indeed\, that's what the perl-loop mailing list has been working on for lo these many months. Any folks from perl-loop want to comment?

Well\, I'm not from perl-loop\, but my idea of the signal handler would be the following pseudocode.

The first time you create a new thread\, Perl transparently installs another thread which loops in   wait_for(signal_semaphore)   check_signal_list(threaded)

The C signal handlers just has to do an up() on the semaphore\, in addition to incrementing the counter for "their" signal; in all other threads\, the single-threaded case's periodic check_signal_list() is a no-op.

The actual calling of the Perl signal handler involves the temporary creation of a new thread; else we'd run into a situation where the SIGUSR1 handler blocks\, and the SIGUSR2 handler can't run because the sig handler thread isn't inside its main loop at the moment. Not good.

You'll have exactly the same concurrency problems that exist today\, of course\, but you now can use locks to protect the critical areas.

-- Matthias Urlichs | noris network GmbH | smurf@​noris.de | ICQ​: 20193661 The quote was selected randomly. Really. | http​://www.noris.de/~smurf/ -- BRILLIANT'S OBSERVATION ON MODERN ART​:   Not all our artists are playing a joke on the public.   Some are genuinely mad.

p5pRT commented 24 years ago

From @timbunce

On Tue\, Jan 11\, 2000 at 02​:06​:52PM -0800\, Larry Wall wrote​:

Ilya Zakharevich writes​: : We *need* an event loop in Perl core - or very close to it. This may : be a part of this loop.

Indeed\, that's what the perl-loop mailing list has been working on for lo these many months. Any folks from perl-loop want to comment?

My (vague) impression is that that work fragmented with one group adding features and others being unhappy that there were too many features. I think it's lost direction and consensus support. Sadly.

Tim.

p5pRT commented 24 years ago

From @AlanBurlison

Just wait until they get onto the french insults...

  Ah don' wanna talk to you no more\, you empty-headed   animal food-trough wiper! Ah fart in our general   direction! Your mother was a hamster\, and your father   smelt of eldeberries!

Alan Burlison

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

g\) anything else you might want to do safely in a signal handler\.

Case in point​: madly trying to get your editor to stop doing the wrong find-and-replace operation you just told it to do over at 10\,000 line file...

(Hmmm. I wonder what would be the performance of a text editor written in Perl?)

Mark Leighton Fisher fisherm@​tce.com Thomson Consumer Electronics Indianapolis IN "Browser Torture Specialist\, First Class"

p5pRT commented 24 years ago

From [Unknown Contact. See original ticket]

On Wed\, Jan 12\, 2000 at 11​:01​:16AM +0000\, Tim.Bunce@​ig.co.uk wrote​:

On Tue\, Jan 11\, 2000 at 02​:06​:52PM -0800\, Larry Wall wrote​:

Ilya Zakharevich writes​: : We *need* an event loop in Perl core - or very close to it. This may : be a part of this loop.

Indeed\, that's what the perl-loop mailing list has been working on for lo these many months. Any folks from perl-loop want to comment?

My (vague) impression is that that work fragmented with one group adding features and others being unhappy that there were too many features. I think it's lost direction and consensus support. Sadly.

That's news to me. Granted\, there was heated discussion for a few months but I believe most folks are now mostly satisfied with the design and implementation. Graham\, Nick\, Gisle and others\, feel free to correct me or forever hold your peace. ;-)

Speaking to the topic of this thread\, I'm not sure how much help Event is to solve the lack of bullet-proof signals. Furthermore\, Event tries to ignore the implications of multiple threads as much as possible. I envision Event running in a single thread and using thread-safe queues (or whatever) to dispatch to worker threads. As far as signal handling\, I have implemented a signal watcher that reliably generates events for signals. The signal handler is as follows​:

static Signal_t process_sighandler(int sig) {   pe_sig_stat *st = &Sigstat[Sigslot];   ++st->Hits;   ++st->hits[sig]; }

The fancy stuff with Sigslot avoids any chance of loosing signals during inspection of the signal counters. The signal counters are polled every iteration through the event loop. This works well for easy stuff\, meaning\, your code is Event driven and doesn't care about signal latency. My hope was that run-time opcode substitution would give us more ways to cope with these nasties. Where does that patch stand?

I usually give up at this point because I can see that signals are a mess and getting them to work with multiple threads is going to make it worse. I am encouraged to hear that linux does not follow POSIX. My experience with POSIX threads has not been very encouraging. My unsubstantiated suspicion is that the POSIX thread spec was written well ahead of any working implementation. I think it is likely that the linux model is better even though I haven't checked myself. This is just a vague feeling. I might be completely backwards here.

I have little idea about Win32. Personally\, I am not interested in doing a port. No volunteer has stepped forward so perhaps we can strike a deal with Microsoft to commission the work. At least I can parrot from those more knowledgable that the Win32 model is *significant* different than Unix. We may want to consider exposing another level of abstraction to the programmer. I'm not sure we can present a consistent\, portable interface without loosing OS specific optimizations. At least the decision should be put off until someone understands all the issues and can say something definite.

Lastly\, I want to make sure that no one forgets about a handler to print the perl stack upon SIGSEGV. Of course perl should never cause a SIGSEGV\, and I trust that p5p (and p6p) can probably assure this\, but I fear we also have to consider the unwashed masses of XS authors (myself included :-).

If you have any further questions\, I'd be happy to share my thoughts. Hope this helps.

-- "Never ascribe to malice that which can be explained by stupidity."   via\, but not speaking for Deutsche Bank

p5pRT commented 24 years ago

From @gbarr

On Wed\, Jan 12\, 2000 at 09​:54​:52AM -0500\, Joshua Pritikin wrote​:

On Wed\, Jan 12\, 2000 at 11​:01​:16AM +0000\, Tim.Bunce@​ig.co.uk wrote​:

On Tue\, Jan 11\, 2000 at 02​:06​:52PM -0800\, Larry Wall wrote​:

Ilya Zakharevich writes​: : We *need* an event loop in Perl core - or very close to it. This may : be a part of this loop.

Indeed\, that's what the perl-loop mailing list has been working on for lo these many months. Any folks from perl-loop want to comment?

My (vague) impression is that that work fragmented with one group adding features and others being unhappy that there were too many features. I think it's lost direction and consensus support. Sadly.

That's news to me. Granted\, there was heated discussion for a few months but I believe most folks are now mostly satisfied with the design and implementation. Graham\, Nick\, Gisle and others\, feel free to correct me or forever hold your peace. ;-)

I did express my opinions some time back that the Event module is evolving to be too complex to be considered as general solution to includ in the standard dist. So I would have to agree with Tim.

That is all I am going to say on the matter as I do not have the time to get into a long drawn out discussion.

Graham.