File: disposal-subs-c.t

package info (click to toggle)
libtcl-perl 1.32%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 288 kB
  • sloc: perl: 417; tcl: 19; makefile: 14
file content (82 lines) | stat: -rw-r--r-- 2,966 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# see how CODE REFs are created and then freed
#  this tests that code is not freed while any after is still using it
# this tests the [$sub,arg,arg,arg] form
#
# v1.02 is good, it never tries to cleanup
#  but it also leaks memory 2 two ways, command-deletion  and $anon_refs
# in  v1.05  they fail after $delay+1 sec
#   1-1) the call to create_tcl_sub
#   1-1-1)  CreateCommand($tclname, $sub, undef, undef, 1) creates the tcl-> perl callback
#   1-1-2}  $anon_refs{$rname} doesnt exist
#   1-1-3}  $anon_refs{$rname} = bless [\$sub, $interp], 'Tcl::Code'; gets set
#   1-2}  its an after command
#   1-2-1}  the constructed after command is run $interp->icall(@args)
#   1-2-2}  the calls bundled in @calls get saved to a new $anon_refs{$synthname}
#   1-2-3}  $anon_refs{$rname} gets deleted, but there is a copy in @calls/$anon_refs{$synthname}, nothing is destroyed
#   1-2-3}  after gets called in $delay+1 secs to delete $anon_refs{$synthname}
#
# that repeats until 1  second after the first delay in the after chain
#  then when the first _code_dispose($synthname) gets called
#
#   2-1)  _code_dispose($k/synthname)
#   2-1-1)  delete $anon_refs{$k};
#   2-1-2}  $anon_refs{$k} does exist  , its an array and all members get destroyed
#   2-1-2-1}  each member was its own Tcl::Code object and is singlar and gets destroyed
#   2-1-2-2)  $interp->DeleteCommand($tclname} runs and destroys the new command
#  but that same $tclname may still be scheduled in later after calls still pending
#
# but later when tcl tries to use $tclname as a command alias, its been destroyed
#   Tcl error 'invalid command name "::perl::CODE(0x8e4e2a8)"
#      at ./blib/lib/Tcl.pm line ####.
#      while invoking scalar result call:
# its just plain gone
#
# i fixed this for v1.06
#  the "weaken" patch version dealt with this a little by keeping weakened $anon_refs{$tclname} as a Tcl::Code
#   that all the other $anon_refs had a copy of, rather than a new Tcl::Code every time
#   so only when the last {$anon_refs{$rname | $synthname} copy was destroyed did the $interp->DeleteCommand($tclname} run
#  but it still suffered from other probs

use Tcl;
use strict; use warnings;

  $| = 1;

  print "1..9\n";

  my $inter=Tcl->new();

  my $ct=0;
  my @queue;
  my $sub;
  $sub=sub{
    my $arg1=shift;
    unless ($arg1 == 0) { exit;}
    return unless (scalar(@queue));
    my $line =shift @queue;
    print $line."\n";
    return unless (scalar(@queue));
    $inter->call('after',200,[$sub,$ct]);
  };

  run_cmd(1);

  flush_afters($inter);
  exit;

sub run_cmd{
  my $name=shift;
  for my $ii (1..9) {push @queue,'ok '.$ii; }
  $inter->call('after',200,[$sub,$ct]);
}

sub flush_afters{
  my $inter=shift;
  while(1) {  # wait for afters to finish
    my @info0=$inter->icall('after', 'info');
    last unless (scalar(@info0));
    $inter->icall('after', 300, 'set var fafafa');
    $inter->icall('vwait', 'var'); # will wait for .3 seconds
  }
} # flush afters