all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Chong Yidong <cyd@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Juanma Barranquero <lekktu@gmail.com>,
	jwalt@garni.ch, 12463@debbugs.gnu.org
Subject: bug#12463: 24.2; pos-visible-in-window-p gets slower over time
Date: Sat, 22 Sep 2012 09:23:37 +0800	[thread overview]
Message-ID: <87lig2q292.fsf@gnu.org> (raw)
In-Reply-To: <83392bxobc.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 21 Sep 2012 20:45:11 +0300")

[-- Attachment #1: Type: text/plain, Size: 340 bytes --]

Juanma helped me spot a few more errors in the patch off-list.  Here's
another iteration.  I added a BLOCK_INPUT in define_image_type; this
seems necessary because lookup_image_type can be called with input
unblocked.

If further testing does not turn up any issues, I'll commit it so that
the Vlibrary_cache refactoring work can proceed.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: image.patch --]
[-- Type: text/x-diff, Size: 15581 bytes --]

=== modified file 'src/dispextern.h'
*** src/dispextern.h	2012-09-13 02:21:28 +0000
--- src/dispextern.h	2012-09-21 09:29:26 +0000
***************
*** 2766,2771 ****
--- 2766,2775 ----
    /* Free resources of image IMG which is used on frame F.  */
    void (* free) (struct frame *f, struct image *img);
  
+   /* Initialization function (used for dynamic loading of image
+      libraries on Windows), or NULL if none.  */
+   int (* init) (Lisp_Object);
+ 
    /* Next in list of all supported image types.  */
    struct image_type *next;
  };

=== modified file 'src/image.c'
*** src/image.c	2012-09-21 03:52:23 +0000
--- src/image.c	2012-09-22 01:19:13 +0000
***************
*** 561,568 ****
  
  /* Function prototypes.  */
  
! static Lisp_Object define_image_type (struct image_type *type, int loaded);
! static struct image_type *lookup_image_type (Lisp_Object symbol);
  static void image_error (const char *format, Lisp_Object, Lisp_Object);
  static void x_laplace (struct frame *, struct image *);
  static void x_emboss (struct frame *, struct image *);
--- 561,568 ----
  
  /* Function prototypes.  */
  
! static struct image_type *define_image_type (struct image_type *, Lisp_Object);
! static struct image_type *lookup_image_type (Lisp_Object, Lisp_Object);
  static void image_error (const char *format, Lisp_Object, Lisp_Object);
  static void x_laplace (struct frame *, struct image *);
  static void x_emboss (struct frame *, struct image *);
***************
*** 579,632 ****
    do { Vimage_types = Fcons (type, Vimage_types); } while (0)
  
  /* Define a new image type from TYPE.  This adds a copy of TYPE to
!    image_types and caches the loading status of TYPE.  */
  
! static Lisp_Object
! define_image_type (struct image_type *type, int loaded)
! {
!   Lisp_Object success;
  
!   if (!loaded)
!     success = Qnil;
!   else
      {
!       struct image_type *p;
!       Lisp_Object target_type = *(type->type);
!       for (p = image_types; p; p = p->next)
!       	if (EQ (*(p->type), target_type))
!       	  return Qt;
  
        /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
           The initialized data segment is read-only.  */
        p = xmalloc (sizeof *p);
        *p = *type;
        p->next = image_types;
        image_types = p;
-       success = Qt;
      }
  
!   CACHE_IMAGE_TYPE (*type->type, success);
!   return success;
! }
! 
! 
! /* Look up image type SYMBOL, and return a pointer to its image_type
!    structure.  Value is null if SYMBOL is not a known image type.  */
! 
! static inline struct image_type *
! lookup_image_type (Lisp_Object symbol)
! {
!   struct image_type *type;
! 
!   /* We must initialize the image-type if it hasn't been already.  */
!   if (NILP (Finit_image_library (symbol, Vdynamic_library_alist)))
!     return 0;			/* unimplemented */
! 
!   for (type = image_types; type; type = type->next)
!     if (EQ (symbol, *type->type))
!       break;
! 
!   return type;
  }
  
  
--- 579,633 ----
    do { Vimage_types = Fcons (type, Vimage_types); } while (0)
  
  /* Define a new image type from TYPE.  This adds a copy of TYPE to
!    image_types and caches the loading status of TYPE.
  
!    LIBRARIES is an alist associating dynamic libraries to external
!    files implementing them, which is passed to the image library
!    initialization function if necessary.  A nil value defaults to
!    Vdynamic_library_alist.  */
! 
! static struct image_type *
! define_image_type (struct image_type *type, Lisp_Object libraries)
! {
!   struct image_type *p = NULL;
!   Lisp_Object target_type = *type->type;
!   int type_valid = 1;
  
!   BLOCK_INPUT;
! 
!   for (p = image_types; p; p = p->next)
!     if (EQ (*p->type, target_type))
!       goto done;
! 
!   if (type->init)
      {
! #ifdef HAVE_NTGUI
!       /* If we failed to load the library before, don't try again.  */
!       Lisp_Object tested = Fassq (target_type, Vlibrary_cache);
!       if (CONSP (tested) && NILP (XCDR (tested)))
! 	type_valid = 0;
!       else
! #endif
! 	{
! 	  /* If the load failed, avoid trying again.  */
! 	  type_valid = type->init (libraries);
! 	  CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil);
! 	}
!     }
  
+   if (type_valid)
+     {
        /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
           The initialized data segment is read-only.  */
        p = xmalloc (sizeof *p);
        *p = *type;
        p->next = image_types;
        image_types = p;
      }
  
!  done:
!   UNBLOCK_INPUT;
!   return p;
  }
  
  
***************
*** 653,659 ****
  	    if (CONSP (tem) && SYMBOLP (XCAR (tem)))
  	      {
  		struct image_type *type;
! 		type = lookup_image_type (XCAR (tem));
  		if (type)
  		  valid_p = type->valid_p (object);
  	      }
--- 654,660 ----
  	    if (CONSP (tem) && SYMBOLP (XCAR (tem)))
  	      {
  		struct image_type *type;
! 		type = lookup_image_type (XCAR (tem), Qnil);
  		if (type)
  		  valid_p = type->valid_p (object);
  	      }
***************
*** 986,992 ****
  
    eassert (valid_image_p (spec));
    img->dependencies = NILP (file) ? Qnil : list1 (file);
!   img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
    eassert (img->type != NULL);
    img->spec = spec;
    img->lisp_data = Qnil;
--- 987,993 ----
  
    eassert (valid_image_p (spec));
    img->dependencies = NILP (file) ? Qnil : list1 (file);
!   img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL), Qnil);
    eassert (img->type != NULL);
    img->spec = spec;
    img->lisp_data = Qnil;
***************
*** 2262,2267 ****
--- 2263,2269 ----
    xbm_image_p,
    xbm_load,
    x_clear_image,
+   NULL,
    NULL
  };
  
***************
*** 3051,3056 ****
--- 3053,3064 ----
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
  
+ #ifdef HAVE_NTGUI
+ static int init_xpm_functions (Lisp_Object);
+ #else
+ #define init_xpm_functions NULL
+ #endif
+ 
  /* Structure describing the image type XPM.  */
  
  static struct image_type xpm_type =
***************
*** 3059,3064 ****
--- 3067,3073 ----
    xpm_image_p,
    xpm_load,
    x_clear_image,
+   init_xpm_functions,
    NULL
  };
  
***************
*** 4981,4986 ****
--- 4990,4996 ----
    pbm_image_p,
    pbm_load,
    x_clear_image,
+   NULL,
    NULL
  };
  
***************
*** 5387,5392 ****
--- 5397,5408 ----
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
  
+ #ifdef HAVE_NTGUI
+ static int init_png_functions (Lisp_Object);
+ #else
+ #define init_png_functions NULL
+ #endif
+ 
  /* Structure describing the image type `png'.  */
  
  static struct image_type png_type =
***************
*** 5395,5400 ****
--- 5411,5417 ----
    png_image_p,
    png_load,
    x_clear_image,
+   init_png_functions,
    NULL
  };
  
***************
*** 6039,6044 ****
--- 6056,6067 ----
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
  
+ #ifdef HAVE_NTGUI
+ static int init_jpeg_functions (Lisp_Object);
+ #else
+ #define init_jpeg_functions NULL
+ #endif
+ 
  /* Structure describing the image type `jpeg'.  */
  
  static struct image_type jpeg_type =
***************
*** 6047,6052 ****
--- 6070,6076 ----
    jpeg_image_p,
    jpeg_load,
    x_clear_image,
+   init_jpeg_functions,
    NULL
  };
  
***************
*** 6624,6629 ****
--- 6648,6659 ----
    {":index",		IMAGE_NON_NEGATIVE_INTEGER_VALUE,	0}
  };
  
+ #ifdef HAVE_NTGUI
+ static int init_tiff_functions (Lisp_Object);
+ #else
+ #define init_tiff_functions NULL
+ #endif
+ 
  /* Structure describing the image type `tiff'.  */
  
  static struct image_type tiff_type =
***************
*** 6632,6637 ****
--- 6662,6668 ----
    tiff_image_p,
    tiff_load,
    x_clear_image,
+   init_tiff_functions,
    NULL
  };
  
***************
*** 7072,7077 ****
--- 7103,7114 ----
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
  
+ #ifdef HAVE_NTGUI
+ static int init_gif_functions (Lisp_Object);
+ #else
+ #define init_gif_functions NULL
+ #endif
+ 
  /* Structure describing the image type `gif'.  */
  
  static struct image_type gif_type =
***************
*** 7080,7085 ****
--- 7117,7123 ----
    gif_image_p,
    gif_load,
    gif_clear_image,
+   init_gif_functions,
    NULL
  };
  
***************
*** 7562,7567 ****
--- 7600,7611 ----
      {":crop",		IMAGE_DONT_CHECK_VALUE_TYPE,		0}
    };
  
+ #ifdef HAVE_NTGUI
+ static int init_imagemagick_functions (Lisp_Object);
+ #else
+ #define init_imagemagick_functions NULL
+ #endif
+ 
  /* Structure describing the image type for any image handled via
     ImageMagick.  */
  
***************
*** 7571,7576 ****
--- 7615,7621 ----
      imagemagick_image_p,
      imagemagick_load,
      imagemagick_clear_image,
+     init_imagemagick_functions,
      NULL
    };
  
***************
*** 8109,8130 ****
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
  
  /* Structure describing the image type `svg'.  Its the same type of
     structure defined for all image formats, handled by emacs image
     functions.  See struct image_type in dispextern.h.  */
  
  static struct image_type svg_type =
  {
-   /* An identifier showing that this is an image structure for the SVG format.  */
    &Qsvg,
-   /* Handle to a function that can be used to identify a SVG file.  */
    svg_image_p,
-   /* Handle to function used to load a SVG file.  */
    svg_load,
-   /* Handle to function to free sresources for SVG.  */
    x_clear_image,
!   /* An internal field to link to the next image type in a list of
!      image types, will be filled in when registering the format.  */
    NULL
  };
  
--- 8154,8176 ----
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
  
+ #ifdef HAVE_NTGUI
+ static int init_svg_functions (Lisp_Object);
+ #else
+ #define init_svg_functions NULL
+ #endif
+ 
  /* Structure describing the image type `svg'.  Its the same type of
     structure defined for all image formats, handled by emacs image
     functions.  See struct image_type in dispextern.h.  */
  
  static struct image_type svg_type =
  {
    &Qsvg,
    svg_image_p,
    svg_load,
    x_clear_image,
!   init_svg_functions,
    NULL
  };
  
***************
*** 8504,8509 ****
--- 8550,8561 ----
    {":background",	IMAGE_STRING_OR_NIL_VALUE,		0}
  };
  
+ #ifdef HAVE_NTGUI
+ static int init_gs_functions (Lisp_Object);
+ #else
+ #define init_gs_functions NULL
+ #endif
+ 
  /* Structure describing the image type `ghostscript'.  */
  
  static struct image_type gs_type =
***************
*** 8512,8517 ****
--- 8564,8570 ----
    gs_image_p,
    gs_load,
    gs_clear_image,
+   init_gs_functions,
    NULL
  };
  
***************
*** 8774,8789 ****
  			    Initialization
   ***********************************************************************/
  
- #ifdef HAVE_NTGUI
- /* Image types that rely on external libraries are loaded dynamically
-    if the library is available.  */
- #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
-   define_image_type (image_type, init_lib_fn (libraries))
- #else
- #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
-   define_image_type (image_type, 1)
- #endif /* HAVE_NTGUI */
- 
  DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
         doc: /* Initialize image library implementing image type TYPE.
  Return non-nil if TYPE is a supported image type.
--- 8827,8832 ----
***************
*** 8793,8853 ****
  of `dynamic-library-alist', which see).  */)
    (Lisp_Object type, Lisp_Object libraries)
  {
! #ifdef HAVE_NTGUI
!   /* Don't try to reload the library.  */
!   Lisp_Object tested = Fassq (type, Vlibrary_cache);
!   if (CONSP (tested))
!     return XCDR (tested);
! #endif
  
    /* Types pbm and xbm are built-in and always available.  */
!   if (EQ (type, Qpbm) || EQ (type, Qxbm))
!     return Qt;
  
  #if defined (HAVE_XPM) || defined (HAVE_NS)
    if (EQ (type, Qxpm))
!     return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
  #endif
  
  #if defined (HAVE_JPEG) || defined (HAVE_NS)
    if (EQ (type, Qjpeg))
!     return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
  #endif
  
  #if defined (HAVE_TIFF) || defined (HAVE_NS)
    if (EQ (type, Qtiff))
!     return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
  #endif
  
  #if defined (HAVE_GIF) || defined (HAVE_NS)
    if (EQ (type, Qgif))
!     return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
  #endif
  
  #if defined (HAVE_PNG) || defined (HAVE_NS)
    if (EQ (type, Qpng))
!     return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
  #endif
  
  #if defined (HAVE_RSVG)
    if (EQ (type, Qsvg))
!     return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
  #endif
  
  #if defined (HAVE_IMAGEMAGICK)
    if (EQ (type, Qimagemagick))
!     return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
!                                 libraries);
  #endif
  
  #ifdef HAVE_GHOSTSCRIPT
    if (EQ (type, Qpostscript))
!     return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
  #endif
  
!   /* If the type is not recognized, avoid testing it ever again.  */
!   CACHE_IMAGE_TYPE (type, Qnil);
!   return Qnil;
  }
  
  void
--- 8836,8906 ----
  of `dynamic-library-alist', which see).  */)
    (Lisp_Object type, Lisp_Object libraries)
  {
!   return lookup_image_type (type, libraries) ? Qt : Qnil;
! }
! 
! /* Look up image type TYPE, and return a pointer to its image_type
!    structure.  Return 0 if TYPE is not a known image type.
! 
!    LIBRARIES is an alist associating dynamic libraries to external
!    files implementing them, which is passed to the image library
!    initialization function if necessary.  A nil value defaults to
!    Vdynamic_library_alist.  */
! 
! static struct image_type *
! lookup_image_type (Lisp_Object type, Lisp_Object libraries)
! {
!   if (NILP (libraries))
!     libraries = Vdynamic_library_alist;
  
    /* Types pbm and xbm are built-in and always available.  */
!   if (EQ (type, Qpbm))
!     return define_image_type (&pbm_type, libraries);
! 
!   if (EQ (type, Qxbm))
!     return define_image_type (&xbm_type, libraries);
  
  #if defined (HAVE_XPM) || defined (HAVE_NS)
    if (EQ (type, Qxpm))
!     return define_image_type (&xpm_type, libraries);
  #endif
  
  #if defined (HAVE_JPEG) || defined (HAVE_NS)
    if (EQ (type, Qjpeg))
!     return define_image_type (&jpeg_type, libraries);
  #endif
  
  #if defined (HAVE_TIFF) || defined (HAVE_NS)
    if (EQ (type, Qtiff))
!     return define_image_type (&tiff_type, libraries);
  #endif
  
  #if defined (HAVE_GIF) || defined (HAVE_NS)
    if (EQ (type, Qgif))
!     return define_image_type (&gif_type, libraries);
  #endif
  
  #if defined (HAVE_PNG) || defined (HAVE_NS)
    if (EQ (type, Qpng))
!     return define_image_type (&png_type, libraries);
  #endif
  
  #if defined (HAVE_RSVG)
    if (EQ (type, Qsvg))
!     return define_image_type (&svg_type, libraries);
  #endif
  
  #if defined (HAVE_IMAGEMAGICK)
    if (EQ (type, Qimagemagick))
!     return define_image_type (&imagemagick_type, libraries);
  #endif
  
  #ifdef HAVE_GHOSTSCRIPT
    if (EQ (type, Qpostscript))
!     return define_image_type (&gs_type, libraries);
  #endif
  
!   return NULL;
  }
  
  void
***************
*** 8884,8892 ****
    DEFSYM (Qxbm, "xbm");
    ADD_IMAGE_TYPE (Qxbm);
  
-   define_image_type (&xbm_type, 1);
-   define_image_type (&pbm_type, 1);
- 
    DEFSYM (Qcount, "count");
    DEFSYM (Qextension_data, "extension-data");
    DEFSYM (Qdelay, "delay");
--- 8937,8942 ----


  reply	other threads:[~2012-09-22  1:23 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-17 23:51 bug#12463: 24.2; pos-visible-in-window-p gets slower over time Jörg Walter
2012-09-18  7:46 ` Eli Zaretskii
2012-09-18  9:46   ` Jörg Walter
2012-09-18 10:23     ` Eli Zaretskii
2012-09-18 15:05     ` Matt Lundin
2012-09-18 16:24       ` Eli Zaretskii
2012-09-18 15:17   ` Chong Yidong
2012-09-18 16:18     ` Jörg Walter
2012-09-20 23:22       ` Juanma Barranquero
2012-09-21  3:52         ` Chong Yidong
2012-09-21  5:42           ` Chong Yidong
2012-09-21  7:34             ` Eli Zaretskii
2012-09-21  9:24               ` Chong Yidong
2012-09-21 10:47                 ` Juanma Barranquero
2012-09-21 12:33                   ` Eli Zaretskii
2012-09-21 16:38                     ` Stefan Monnier
2012-09-21 16:58                       ` Eli Zaretskii
2012-09-21 20:34                         ` Stefan Monnier
2012-09-22  6:58                           ` Eli Zaretskii
2012-09-22 20:20                             ` Stefan Monnier
2012-09-22 20:31                               ` Juanma Barranquero
2012-09-23  9:17                                 ` Chong Yidong
2012-09-23  3:50                               ` Eli Zaretskii
2012-09-21  9:10             ` Juanma Barranquero
2012-09-21 10:01               ` Chong Yidong
2012-09-21 17:03                 ` Eli Zaretskii
2012-09-21 17:07                   ` Juanma Barranquero
2012-09-21 17:45                     ` Eli Zaretskii
2012-09-22  1:23                       ` Chong Yidong [this message]
2012-09-22  8:36                         ` Eli Zaretskii
2012-09-22 11:05                           ` Chong Yidong
2012-09-22 11:18                             ` Eli Zaretskii
2012-09-22 14:14                               ` Chong Yidong
2012-09-22 14:25                                 ` Eli Zaretskii
2012-09-22 19:20                                 ` Juanma Barranquero
2012-09-22 19:46                                   ` Eli Zaretskii
2012-09-22 19:53                                     ` Juanma Barranquero
2012-09-23  3:48                                       ` Eli Zaretskii
2012-09-21  6:58           ` Eli Zaretskii
2012-09-21  8:36           ` Juanma Barranquero
2012-09-21  9:11             ` Chong Yidong
2012-09-21  9:17               ` Juanma Barranquero
2012-09-18 16:19     ` Eli Zaretskii
2012-09-18 16:26       ` Jörg Walter
2012-09-18 17:19         ` Eli Zaretskii
2012-09-18 17:31           ` Juanma Barranquero
2012-09-18 20:00             ` Eli Zaretskii
2012-09-19  2:31               ` Juanma Barranquero
2012-09-19  2:57                 ` Eli Zaretskii
2012-09-19  3:03                   ` Juanma Barranquero

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87lig2q292.fsf@gnu.org \
    --to=cyd@gnu.org \
    --cc=12463@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=jwalt@garni.ch \
    --cc=lekktu@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.