- fix POD nits
https://rt.cpan.org/Ticket/Display.html?id=51874
+ - prevent double-frees when someone creates Imager objects and then
+ creates a thread. Note: this just handles some simple cases,
+ Imager doesn't support perl threads, and isn't likely to.
+ https://rt.cpan.org/Ticket/Display.html?id=52268
+
Imager 0.71 - 16 Nov 2009
===========
cd => 1.0,
cs => 40,
n => 1.3,
- Ia => Imager::Color->new(rgb=>[0,0,0]),
- Il => Imager::Color->new(rgb=>[255,255,255]),
- Is => Imager::Color->new(rgb=>[255,255,255]),
+ Ia => [0,0,0],
+ Il => [255,255,255],
+ Is => [255,255,255],
},
callsub => sub {
my %hsh = @_;
+ for my $cname (qw/Ia Il Is/) {
+ my $old = $hsh{$cname};
+ my $new_color = _color($old)
+ or die $Imager::ERRSTR, "\n";
+ $hsh{$cname} = $new_color;
+ }
i_bumpmap_complex($hsh{image}, $hsh{bump}{IMG}, $hsh{channel},
$hsh{tx}, $hsh{ty}, $hsh{Lx}, $hsh{Ly}, $hsh{Lz},
$hsh{cd}, $hsh{cs}, $hsh{n}, $hsh{Ia}, $hsh{Il},
super_sample => 0, ssample_param => 4,
segments=>[
[ 0, 0.5, 1,
- Imager::Color->new(0,0,0),
- Imager::Color->new(255, 255, 255),
+ [0,0,0],
+ [255, 255, 255],
0, 0,
],
],
return Imager::ExtUtils->inline_config;
}
+# threads shouldn't try to close raw Imager objects
+sub Imager::ImgRaw::CLONE_SKIP { 1 }
+
1;
__END__
# Below is the stub of documentation for your module. You better edit it!
writing an image to a file - L<Imager::Files>
+=head1 THREADS
+
+Imager doesn't support perl threads.
+
+Imager has limited code to prevent double frees if you create images,
+colors etc, and then create a thread, but has no code to prevent two
+threads entering Imager's error handling code, and none is likely to
+be added.
+
=head1 SUPPORT
The best place to get help with Imager is the mailing list.
myfree(hlines);
}
+#define i_int_hlines_CLONE_SKIP(cls) 1
+
static int seg_compare(const void *vleft, const void *vright) {
const i_int_hline_seg *left = vleft;
const i_int_hline_seg *right = vright;
i_io_DESTROY(ig)
Imager::IO ig
+int
+i_io_CLONE_SKIP(...)
+ CODE:
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL
+
MODULE = Imager PACKAGE = Imager
PROTOTYPES: ENABLE
TT_DESTROY(handle)
Imager::Font::TT handle
+int
+TT_CLONE_SKIP(...)
+ CODE:
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL
+
MODULE = Imager PACKAGE = Imager
FT2_DESTROY(font)
Imager::Font::FT2 font
+int
+FT2_CLONE_SKIP(...)
+ CODE:
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL
+
MODULE = Imager PACKAGE = Imager::Font::FreeType2
Imager::Font::FT2
IFILL_DESTROY(fill)
Imager::FillHandle fill
+int
+IFILL_CLONE_SKIP(...)
+ CODE:
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL
+
MODULE = Imager PACKAGE = Imager
Imager::FillHandle
i_int_hlines_dump(hlines)
Imager::Internal::Hlines hlines
+int
+i_int_hlines_CLONE_SKIP(cls)
+ SV *cls
+
#endif
BOOT:
return 1;
}
+sub CLONE_SKIP { 1 }
+
1;
__END__
return @arg ? set_internal($self, $arg[0],$arg[1],$arg[2],$arg[3]) : ();
}
+sub CLONE_SKIP { 1 }
+
1;
__END__
--- /dev/null
+#!perl
+use strict;
+use Imager;
+use Imager::Color::Float;
+use Imager::Fill;
+use threads;
+use Config;
+use Test::More;
+
+$Config{useithreads}
+ or plan skip_all => "can't test Imager's lack of threads support with no threads";
+
+plan tests => 11;
+
+my $thread = threads->create(sub { 1; });
+ok($thread->join, "join first thread");
+
+# these are all, or contain, XS allocated objects, if we don't
+# probably handle CLONE requests, or provide a CLONE_SKIP, we'll
+# probably see a double-free, one from the thread, and the other from
+# the main line of control.
+# So make one of each
+
+my $im = Imager->new(xsize => 10, ysize => 10);
+my $c = Imager::Color->new(0, 0, 0); # make some sort of color
+ok($c, "made the color");
+my $cf = Imager::Color::Float->new(0, 0, 0);
+ok($cf, "made the float color");
+my $hl;
+SKIP:
+{
+ Imager::Internal::Hlines::testing()
+ or skip "no hlines visible to test", 1;
+ $hl = Imager::Internal::Hlines::new(0, 100, 0, 100);
+ ok($hl, "made the hlines");
+}
+my $io = Imager::io_new_bufchain();
+ok($io, "made the io");
+my $tt;
+SKIP:
+{
+ $Imager::formats{tt}
+ or skip("No TT font support", 1);
+ $tt = Imager::Font->new(type => "tt", file => "fontfiles/dodge.ttf");
+ ok($tt, "made the font");
+}
+my $ft2;
+SKIP:
+{
+ $Imager::formats{ft2}
+ or skip "No FT2 support", 1;
+ $ft2 = Imager::Font->new(type => "ft2", file => "fontfiles/dodge.ttf");
+ ok($ft2, "made ft2 font");
+}
+my $fill = Imager::Fill->new(solid => $c);
+ok($fill, "made the fill");
+
+my $t2 = threads->create
+ (
+ sub {
+ ok(!UNIVERSAL::isa($im->{IMG}, "Imager::ImgRaw"),
+ "the low level image object should be undef");
+ 1;
+ }
+ );
+ok($t2->join, "join second thread");
+#print STDERR $im->{IMG}, "\n";
+ok(UNIVERSAL::isa($im->{IMG}, "Imager::ImgRaw"),
+ "but the object should be fine in the main thread");
+