From 88986fdbef795c61cd60231046663d3cd80b4947 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 6 May 2010 10:46:49 +0100 Subject: xlib: Remove reference counting for cairo_xlib_screen_t The screen is owned by the cairo_xlib_display_t device, so we can simplify and close the refleak by removing the surplus reference counting. --- src/cairo-xlib-display.c | 84 +++++++++++------------------------------------- src/cairo-xlib-private.h | 22 +++---------- src/cairo-xlib-screen.c | 47 ++++++--------------------- src/cairo-xlib-surface.c | 38 +++++++--------------- src/cairo-xlib-visual.c | 2 +- 5 files changed, 46 insertions(+), 147 deletions(-) diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c index afa75327..a86c2062 100644 --- a/src/cairo-xlib-display.c +++ b/src/cairo-xlib-display.c @@ -73,10 +73,10 @@ _cairo_xlib_remove_close_display_hook_internal (cairo_xlib_display_t *display, static void _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display) { - cairo_xlib_screen_t *screen; - cairo_xlib_hook_t *hook; + cairo_xlib_screen_t *screen; + cairo_xlib_hook_t *hook; - for (screen = display->screens; screen != NULL; screen = screen->next) + cairo_list_foreach_entry (screen, cairo_xlib_screen_t, &display->screens, link) _cairo_xlib_screen_close_display (display, screen); while (TRUE) { @@ -91,22 +91,6 @@ _cairo_xlib_call_close_display_hooks (cairo_xlib_display_t *display) display->closed = TRUE; } -static void -_cairo_xlib_display_discard_screens (cairo_xlib_display_t *display) -{ - cairo_xlib_screen_t *screens; - - screens = display->screens; - display->screens = NULL; - - while (screens != NULL) { - cairo_xlib_screen_t *screen = screens; - screens = screen->next; - - _cairo_xlib_screen_destroy (screen); - } -} - static void _cairo_xlib_display_finish (void *abstract_display) { @@ -132,6 +116,12 @@ _cairo_xlib_display_destroy (void *abstract_display) } _cairo_freelist_fini (&display->wq_freelist); + while (! cairo_list_is_empty (&display->screens)) { + _cairo_xlib_screen_destroy (cairo_list_first_entry (&display->screens, + cairo_xlib_screen_t, + link)); + } + free (display); } @@ -216,7 +206,6 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes) _cairo_xlib_display_notify (display); _cairo_xlib_call_close_display_hooks (display); - _cairo_xlib_display_discard_screens (display); /* catch any that arrived before marking the display as closed */ _cairo_xlib_display_notify (display); @@ -353,7 +342,7 @@ _cairo_xlib_device_create (Display *dpy) cairo_device_reference (&display->base); /* add one for the CloseDisplay */ display->display = dpy; - display->screens = NULL; + cairo_list_init (&display->screens); display->workqueue = NULL; display->close_display_hooks = NULL; display->closed = FALSE; @@ -610,56 +599,21 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display, return xrender_format; } -void -_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display, - cairo_xlib_screen_t *screen) -{ - cairo_xlib_screen_t **prev; - cairo_xlib_screen_t *list; - - for (prev = &display->screens; (list = *prev); prev = &list->next) { - if (list == screen) { - *prev = screen->next; - break; - } - } -} - -cairo_status_t +cairo_xlib_screen_t * _cairo_xlib_display_get_screen (cairo_xlib_display_t *display, - Screen *screen, - cairo_xlib_screen_t **out) + Screen *screen) { - cairo_xlib_screen_t *info = NULL, **prev; - - if (display->closed) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); + cairo_xlib_screen_t *info; - for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) { + cairo_list_foreach_entry (info, cairo_xlib_screen_t, &display->screens, link) { if (info->screen == screen) { - /* - * MRU the list - */ - if (prev != &display->screens) { - *prev = info->next; - info->next = display->screens; - display->screens = info; - } - break; - } + if (display->screens.next != &info->link) + cairo_list_move (&info->link, &display->screens); + return info; + } } - *out = info; - return CAIRO_STATUS_SUCCESS; -} - - -void -_cairo_xlib_display_add_screen (cairo_xlib_display_t *display, - cairo_xlib_screen_t *screen) -{ - screen->next = display->screens; - display->screens = screen; + return NULL; } void diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h index 345f3e13..24bf5e32 100644 --- a/src/cairo-xlib-private.h +++ b/src/cairo-xlib-private.h @@ -71,7 +71,7 @@ struct _cairo_xlib_display { cairo_xlib_display_t *next; Display *display; - cairo_xlib_screen_t *screens; + cairo_list_t screens; int render_major; int render_minor; @@ -98,8 +98,7 @@ typedef struct _cairo_xlib_visual_info { } cairo_xlib_visual_info_t; struct _cairo_xlib_screen { - cairo_xlib_screen_t *next; - cairo_reference_count_t ref_count; + cairo_list_t link; cairo_device_t *device; Screen *screen; @@ -116,18 +115,9 @@ struct _cairo_xlib_screen { cairo_private cairo_device_t * _cairo_xlib_device_create (Display *display); -cairo_private void -_cairo_xlib_display_add_screen (cairo_xlib_display_t *display, - cairo_xlib_screen_t *screen); - -cairo_private cairo_status_t +cairo_private cairo_xlib_screen_t * _cairo_xlib_display_get_screen (cairo_xlib_display_t *display, - Screen *screen, - cairo_xlib_screen_t **out); - -cairo_private void -_cairo_xlib_display_remove_screen (cairo_xlib_display_t *display, - cairo_xlib_screen_t *screen); + Screen *screen); cairo_private void _cairo_xlib_add_close_display_hook (cairo_xlib_display_t *display, cairo_xlib_hook_t *hook); @@ -170,8 +160,6 @@ _cairo_xlib_screen_get (Display *dpy, Screen *screen, cairo_xlib_screen_t **out); -cairo_private cairo_xlib_screen_t * -_cairo_xlib_screen_reference (cairo_xlib_screen_t *info); cairo_private void _cairo_xlib_screen_destroy (cairo_xlib_screen_t *info); @@ -207,6 +195,6 @@ _cairo_xlib_visual_info_create (Display *dpy, cairo_xlib_visual_info_t **out); cairo_private void -_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info); +_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info); #endif /* CAIRO_XLIB_PRIVATE_H */ diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c index d1d9cf6c..b094eaf4 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -256,16 +256,6 @@ _cairo_xlib_init_screen_font_options (Display *dpy, cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON); } -cairo_xlib_screen_t * -_cairo_xlib_screen_reference (cairo_xlib_screen_t *info) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); - - _cairo_reference_count_inc (&info->ref_count); - - return info; -} - void _cairo_xlib_screen_close_display (cairo_xlib_display_t *display, cairo_xlib_screen_t *info) @@ -274,37 +264,25 @@ _cairo_xlib_screen_close_display (cairo_xlib_display_t *display, int i; dpy = display->display; + for (i = 0; i < ARRAY_LENGTH (info->gc); i++) { if ((info->gc_depths >> (8*i)) & 0xff) XFreeGC (dpy, info->gc[i]); } info->gc_depths = 0; - - while (! cairo_list_is_empty (&info->visuals)) { - _cairo_xlib_visual_info_destroy (dpy, - cairo_list_first_entry (&info->visuals, - cairo_xlib_visual_info_t, - link)); - } } void _cairo_xlib_screen_destroy (cairo_xlib_screen_t *info) { - cairo_xlib_display_t *display; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&info->ref_count)) - return; - - if (! _cairo_xlib_display_acquire (info->device, &display)) { - _cairo_xlib_display_remove_screen (display, info); - _cairo_xlib_screen_close_display (display, info); - - cairo_device_release (&display->base); + while (! cairo_list_is_empty (&info->visuals)) { + _cairo_xlib_visual_info_destroy (cairo_list_first_entry (&info->visuals, + cairo_xlib_visual_info_t, + link)); } + cairo_list_del (&info->link); + free (info); } @@ -327,12 +305,9 @@ _cairo_xlib_screen_get (Display *dpy, if (unlikely (status)) goto CLEANUP_DEVICE; - status = _cairo_xlib_display_get_screen (display, screen, &info); - if (unlikely (status)) - goto CLEANUP_DISPLAY; - + info = _cairo_xlib_display_get_screen (display, screen); if (info != NULL) { - *out = _cairo_xlib_screen_reference (info); + *out = info; goto CLEANUP_DISPLAY; } @@ -342,7 +317,6 @@ _cairo_xlib_screen_get (Display *dpy, goto CLEANUP_DISPLAY; } - CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */ info->device = device; info->screen = screen; info->has_font_options = FALSE; @@ -350,8 +324,7 @@ _cairo_xlib_screen_get (Display *dpy, memset (info->gc, 0, sizeof (info->gc)); cairo_list_init (&info->visuals); - - _cairo_xlib_display_add_screen (display, info); + cairo_list_add (&info->link, &display->screens); *out = info; diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index fa7d6452..3b01fdeb 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -415,8 +415,6 @@ _cairo_xlib_surface_finish (void *abstract_surface) cairo_device_release (&display->base); - _cairo_xlib_screen_destroy (surface->screen); - cairo_region_destroy (surface->clip_region); return status; @@ -2947,8 +2945,6 @@ _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen, cairo_xlib_surface_t *surface; cairo_xlib_display_t *display; cairo_status_t status; - - CAIRO_MUTEX_INITIALIZE (); if (depth == 0) { if (xrender_format) { @@ -3019,7 +3015,7 @@ found: surface->close_display_hook.func = _cairo_xlib_surface_detach_display; _cairo_xlib_add_close_display_hook (display, &surface->close_display_hook); - + cairo_device_release (&display->base); _cairo_surface_init (&surface->base, @@ -3027,7 +3023,7 @@ found: screen->device, _xrender_format_to_content (xrender_format)); - surface->screen = _cairo_xlib_screen_reference (screen); + surface->screen = screen; surface->drawable = drawable; surface->owns_pixmap = FALSE; @@ -3161,7 +3157,6 @@ cairo_xlib_surface_create (Display *dpy, { Screen *scr; cairo_xlib_screen_t *screen; - cairo_surface_t *surface; cairo_status_t status; if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) { @@ -3179,12 +3174,9 @@ cairo_xlib_surface_create (Display *dpy, X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable)); - surface = _cairo_xlib_surface_create_internal (screen, drawable, - visual, NULL, - width, height, 0); - _cairo_xlib_screen_destroy (screen); - - return surface; + return _cairo_xlib_surface_create_internal (screen, drawable, + visual, NULL, + width, height, 0); } slim_hidden_def (cairo_xlib_surface_create); @@ -3209,7 +3201,6 @@ cairo_xlib_surface_create_for_bitmap (Display *dpy, int height) { cairo_xlib_screen_t *screen; - cairo_surface_t *surface; cairo_status_t status; if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) @@ -3221,12 +3212,9 @@ cairo_xlib_surface_create_for_bitmap (Display *dpy, X_DEBUG ((dpy, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap)); - surface = _cairo_xlib_surface_create_internal (screen, bitmap, - NULL, NULL, - width, height, 1); - _cairo_xlib_screen_destroy (screen); - - return surface; + return _cairo_xlib_surface_create_internal (screen, bitmap, + NULL, NULL, + width, height, 1); } #if CAIRO_HAS_XLIB_XRENDER_SURFACE @@ -3259,7 +3247,6 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy, int height) { cairo_xlib_screen_t *screen; - cairo_surface_t *surface; cairo_status_t status; if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) @@ -3271,12 +3258,9 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy, X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable)); - surface = _cairo_xlib_surface_create_internal (screen, drawable, - NULL, format, - width, height, 0); - _cairo_xlib_screen_destroy (screen); - - return surface; + return _cairo_xlib_surface_create_internal (screen, drawable, + NULL, format, + width, height, 0); } slim_hidden_def (cairo_xlib_surface_create_with_xrender_format); diff --git a/src/cairo-xlib-visual.c b/src/cairo-xlib-visual.c index a76bf357..e076ed01 100644 --- a/src/cairo-xlib-visual.c +++ b/src/cairo-xlib-visual.c @@ -180,7 +180,7 @@ _cairo_xlib_visual_info_create (Display *dpy, } void -_cairo_xlib_visual_info_destroy (Display *dpy, cairo_xlib_visual_info_t *info) +_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info) { /* No need for XFreeColors() whilst using DefaultColormap */ free (info); -- cgit v1.2.3