summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2019-08-16 11:45:01 +0100
committerRobin Watts <Robin.Watts@artifex.com>2019-08-21 17:58:15 +0100
commit3bf47403e4cb305222834dca4ab49ce892b838f2 (patch)
treee95ed7dca1d9c1023cdf234ac9db298af0c74fdd
parent075eaec7a08dd585aac81c640aac228a21f7ca69 (diff)
downloadghostpdl-3bf47403e4cb305222834dca4ab49ce892b838f2.tar.gz
Fix X11 device ICC profile memory leaks
When the x11 devices are running in "buffered mode" (i.e. we render to a pixmap, then blit the pixmap to the X11 Window), we create a memory device which actually does the rendering. The memory device takes a reference to the ICC profiles from the x11 device and it is reference counted. Firstly, we always incremented the reference count, ignoring the posibility that we were resizing an existing memory device rather than creating a new one. Secondly, when shutting down the x11 device, we ignored posibility that buffering was in force, and failed to free the memory device - most of the memory was hoovered up by the garbager, but the ICC profile data isn't in gc memory, hence showing a leak. So, fix the memory device ICC reference counting, and reconfigure the device as non-buffering before we shut it down.
-rw-r--r--devices/gdevxini.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/devices/gdevxini.c b/devices/gdevxini.c
index 98c743a95..3b46b1824 100644
--- a/devices/gdevxini.c
+++ b/devices/gdevxini.c
@@ -634,6 +634,7 @@ x_set_buffer(gx_device_X * xdev)
xdev->buffer = buffer;
mdev->width = xdev->width;
mdev->height = xdev->height;
+ rc_decrement(mdev->icc_struct, "x_set_buffer");
mdev->icc_struct = xdev->icc_struct;
rc_increment(xdev->icc_struct);
mdev->color_info = xdev->orig_color_info;
@@ -939,6 +940,8 @@ gdev_x_put_params(gx_device * dev, gs_param_list * plist)
int
gdev_x_close(gx_device_X *xdev)
{
+ long MaxBitmap = xdev->space_params.MaxBitmap;
+
if (xdev->ghostview)
gdev_x_send_event(xdev, xdev->DONE);
if (xdev->vinfo) {
@@ -952,5 +955,10 @@ gdev_x_close(gx_device_X *xdev)
XFreeGC(xdev->dpy, xdev->gc);
XCloseDisplay(xdev->dpy);
+ /* MaxBitmap == 0 ensures x_set_buffer() configures as non-buffering */
+ xdev->space_params.MaxBitmap = 0;
+ x_set_buffer(xdev);
+ xdev->space_params.MaxBitmap = MaxBitmap;
+
return 0;
}