From 4fa20d8f8d01369a5f783cb2203c908b6bad778b Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 20 Apr 2014 17:31:59 -0700 Subject: Spelling fixes. --- src/conf_post.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/conf_post.h b/src/conf_post.h index 8fabd60871b..312f2389415 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -123,7 +123,7 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */ #endif /* We must intercept 'opendir' calls to stash away the directory name, - so we could reuse it in realinkat, see msdos.c. */ + so we could reuse it in readlinkat; see msdos.c. */ #define opendir sys_opendir /* The "portable" definition of _GL_INLINE on config.h does not work -- cgit v1.2.1 From 6709d4dab9d434dcd1d797e081dfc796b735a1ff Mon Sep 17 00:00:00 2001 From: Jarek Czekalski Date: Mon, 21 Apr 2014 11:55:28 -0400 Subject: Fix freezing with scroll bars of GTK3 Toolkit. * src/keyboard.c (unblock_input): Add comment. * src/xgselect.c (xg_select): Prevent Glib main loop recursion. Fixes: debbugs:15801 --- src/ChangeLog | 6 ++++++ src/keyboard.c | 7 ++++++- src/xgselect.c | 25 ++++++++++++++++++------- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index c42679d54f4..e8fb5f63203 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2014-04-21 Jarek Czekalski + + Fix freezing with scroll bars of GTK3 Toolkit (bug#15801). + * keyboard.c (unblock_input): Add comment. + * xgselect.c (xg_select): Prevent Glib main loop recursion. + 2014-04-19 Stefan Monnier * intervals.c (rotate_right, rotate_left): Fix up length computation. diff --git a/src/keyboard.c b/src/keyboard.c index 1f4b23d9905..90479375072 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -7121,7 +7121,12 @@ unblock_input_to (int level) /* End critical section. If doing signal-driven input, and a signal came in when input was - blocked, reinvoke the signal handler now to deal with it. */ + blocked, reinvoke the signal handler now to deal with it. + + It will also process queued input, if it was not read before. + When a longer code sequence does not use block/unblock input + at all, the whole input gathered up to the next call to + unblock_input will be processed inside that call. */ void unblock_input (void) diff --git a/src/xgselect.c b/src/xgselect.c index 1d3f916c9f8..42fdfed0d34 100644 --- a/src/xgselect.c +++ b/src/xgselect.c @@ -28,6 +28,18 @@ along with GNU Emacs. If not, see . */ #include #include #include "frame.h" +#include "blockinput.h" + +/* `xg_select' is a `pselect' replacement. Why do we need a separate function? + 1. Timeouts. Glib and Gtk rely on timer events. If we did pselect + with a greater timeout then the one scheduled by Glib, we would + not allow Glib to process its timer events. We want Glib to + work smoothly, so we need to reduce our timeout to match Glib. + 2. Descriptors. Glib may listen to more file descriptors than we do. + So we add Glib descriptors to our pselect pool, but we don't change + the value returned by the function. The return value matches only + the descriptors passed as arguments, making it compatible with + plain pselect. */ int xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, @@ -47,12 +59,6 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, bool need_to_dispatch; USE_SAFE_ALLOCA; - /* Do not try to optimize with an initial check with g_main_context_pending - and a call to pselect if it returns false. If Gdk has a timeout for 0.01 - second, and Emacs has a timeout for 1 second, g_main_context_pending will - return false, but the timeout will be 1 second, thus missing the gdk - timeout with a lot. */ - context = g_main_context_default (); if (rfds) all_rfds = *rfds; @@ -136,8 +142,13 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, if (need_to_dispatch) { int pselect_errno = errno; + /* Prevent g_main_dispatch recursion, that would occur without + block_input wrapper, because event handlers call + unblock_input. Event loop recursion was causing Bug#15801. */ + block_input (); while (g_main_context_pending (context)) - g_main_context_dispatch (context); + g_main_context_dispatch (context); + unblock_input (); errno = pselect_errno; } -- cgit v1.2.1 From 2f999d5275f7aab04d9e1aedc35d7c33eba94e2d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 22 Apr 2014 20:37:35 +0300 Subject: Add debugging facility for the newline cache. See the discussion in http://lists.gnu.org/archive/html/emacs-devel/2014-04/msg00295.html for more detail. src/search.c (find_newline1): New subroutine. (Fnewline_cache_check): New function. (syms_of_search): Defsubr it. --- src/ChangeLog | 6 +++ src/search.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index e8fb5f63203..98d607046c6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2014-04-22 Eli Zaretskii + + * search.c (find_newline1): New subroutine. + (Fnewline_cache_check): New function. + (syms_of_search): Defsubr it. + 2014-04-21 Jarek Czekalski Fix freezing with scroll bars of GTK3 Toolkit (bug#15801). diff --git a/src/search.c b/src/search.c index 3de194c5056..97087307be3 100644 --- a/src/search.c +++ b/src/search.c @@ -3108,6 +3108,170 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0, out - temp, STRING_MULTIBYTE (string)); } + +/* Like find_newline, but doesn't use the cache, and only searches forward. */ +static ptrdiff_t +find_newline1 (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, + ptrdiff_t end_byte, ptrdiff_t count, ptrdiff_t *shortage, + ptrdiff_t *bytepos, bool allow_quit) +{ + if (count > 0) + { + if (!end) + end = ZV, end_byte = ZV_BYTE; + } + else + { + if (!end) + end = BEGV, end_byte = BEGV_BYTE; + } + if (end_byte == -1) + end_byte = CHAR_TO_BYTE (end); + + if (shortage != 0) + *shortage = 0; + + immediate_quit = allow_quit; + + if (count > 0) + while (start != end) + { + /* Our innermost scanning loop is very simple; it doesn't know + about gaps, buffer ends, or the newline cache. ceiling is + the position of the last character before the next such + obstacle --- the last character the dumb search loop should + examine. */ + ptrdiff_t tem, ceiling_byte = end_byte - 1; + + if (start_byte == -1) + start_byte = CHAR_TO_BYTE (start); + + /* The dumb loop can only scan text stored in contiguous + bytes. BUFFER_CEILING_OF returns the last character + position that is contiguous, so the ceiling is the + position after that. */ + tem = BUFFER_CEILING_OF (start_byte); + ceiling_byte = min (tem, ceiling_byte); + + { + /* The termination address of the dumb loop. */ + unsigned char *lim_addr = BYTE_POS_ADDR (ceiling_byte) + 1; + ptrdiff_t lim_byte = ceiling_byte + 1; + + /* Nonpositive offsets (relative to LIM_ADDR and LIM_BYTE) + of the base, the cursor, and the next line. */ + ptrdiff_t base = start_byte - lim_byte; + ptrdiff_t cursor, next; + + for (cursor = base; cursor < 0; cursor = next) + { + /* The dumb loop. */ + unsigned char *nl = memchr (lim_addr + cursor, '\n', - cursor); + next = nl ? nl - lim_addr : 0; + + if (! nl) + break; + next++; + + if (--count == 0) + { + immediate_quit = 0; + if (bytepos) + *bytepos = lim_byte + next; + return BYTE_TO_CHAR (lim_byte + next); + } + } + + start_byte = lim_byte; + start = BYTE_TO_CHAR (start_byte); + } + } + + immediate_quit = 0; + if (shortage) + *shortage = count; + if (bytepos) + { + *bytepos = start_byte == -1 ? CHAR_TO_BYTE (start) : start_byte; + eassert (*bytepos == CHAR_TO_BYTE (start)); + } + return start; +} + +DEFUN ("newline-cache-check", Fnewline_cache_check, Snewline_cache_check, + 0, 1, 0, + doc: /* Check the newline cache of BUFFER against buffer contents. + +BUFFER defaults to the current buffer. + +Value is an array of 2 sub-arrays of buffer positions for newlines, +the first based on the cache, the second based on actually scanning +the buffer. If the buffer doesn't have a cache, the value is nil. */) + (Lisp_Object buffer) +{ + struct buffer *buf; + struct region_cache *nlcache; + ptrdiff_t shortage, nl_count_cache, nl_count_buf; + Lisp_Object cache_newlines, buf_newlines, val; + ptrdiff_t from, from_byte, found, i; + + if (NILP (buffer)) + buf = current_buffer; + else + { + CHECK_BUFFER (buffer); + buf = XBUFFER (buffer); + } + if (buf->base_buffer) + buf = buf->base_buffer; + + /* If the buffer doesn't have a newline cache, return nil. */ + if (NILP (BVAR (buf, cache_long_scans)) + || buf->newline_cache == NULL) + return Qnil; + + /* How many newlines are there according to the cache? */ + find_newline (BUF_BEG (buf), BUF_BEG_BYTE (buf), + BUF_Z (buf), BUF_Z_BYTE (buf), + TYPE_MAXIMUM (ptrdiff_t), &shortage, NULL, true); + nl_count_cache = TYPE_MAXIMUM (ptrdiff_t) - shortage; + + /* Create vector and populate it. */ + cache_newlines = make_uninit_vector (nl_count_cache); + for (from = BUF_BEG( buf), found = from, i = 0; + from < BUF_Z (buf); + from = found, i++) + { + ptrdiff_t from_byte = CHAR_TO_BYTE (from); + + found = find_newline (from, from_byte, 0, -1, 1, &shortage, NULL, true); + if (shortage == 0) + ASET (cache_newlines, i, make_number (found - 1)); + } + + /* Now do the same, but without using the cache. */ + find_newline1 (BUF_BEG (buf), BUF_BEG_BYTE (buf), + BUF_Z (buf), BUF_Z_BYTE (buf), + TYPE_MAXIMUM (ptrdiff_t), &shortage, NULL, true); + nl_count_buf = TYPE_MAXIMUM (ptrdiff_t) - shortage; + buf_newlines = make_uninit_vector (nl_count_buf); + for (from = BUF_BEG( buf), found = from, i = 0; + from < BUF_Z (buf); + from = found, i++) + { + ptrdiff_t from_byte = CHAR_TO_BYTE (from); + + found = find_newline1 (from, from_byte, 0, -1, 1, &shortage, NULL, true); + if (shortage == 0) + ASET (buf_newlines, i, make_number (found - 1)); + } + + /* Construct the value and return it. */ + val = make_uninit_vector (2); + ASET (val, 0, cache_newlines); + ASET (val, 1, buf_newlines); + return val; +} void syms_of_search (void) @@ -3180,4 +3344,5 @@ is to bind it with `let' around a small expression. */); defsubr (&Smatch_data); defsubr (&Sset_match_data); defsubr (&Sregexp_quote); + defsubr (&Snewline_cache_check); } -- cgit v1.2.1 From 0fae5004bc971311f4abaa6acb073c4551eda7d5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 22 Apr 2014 13:13:59 -0700 Subject: * search.c (Fnewline_cache_check): Remove unused locals. --- src/ChangeLog | 4 ++++ src/search.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 98d607046c6..2ac144f45a0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2014-04-22 Paul Eggert + + * search.c (Fnewline_cache_check): Remove unused locals. + 2014-04-22 Eli Zaretskii * search.c (find_newline1): New subroutine. diff --git a/src/search.c b/src/search.c index 97087307be3..ab390faf82e 100644 --- a/src/search.c +++ b/src/search.c @@ -3210,10 +3210,9 @@ the buffer. If the buffer doesn't have a cache, the value is nil. */) (Lisp_Object buffer) { struct buffer *buf; - struct region_cache *nlcache; ptrdiff_t shortage, nl_count_cache, nl_count_buf; Lisp_Object cache_newlines, buf_newlines, val; - ptrdiff_t from, from_byte, found, i; + ptrdiff_t from, found, i; if (NILP (buffer)) buf = current_buffer; -- cgit v1.2.1 From 34e856d5ac828753b7be20e2471f39fb613f7f40 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 22 Apr 2014 13:19:17 -0700 Subject: Port to GCC 4.9.0 with --enable-gcc-warnings. * image.c (struct my_jpeg_error_mgr) [lint]: Remove member fp. All uses removed. (jpeg_load_body) [lint]: Add a 'volatile' to pacify a buggy GCC in a way that also works with GCC 4.9.0. --- src/ChangeLog | 6 ++++++ src/image.c | 11 ++--------- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ChangeLog b/src/ChangeLog index 2ac144f45a0..6e2f7057b75 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,11 @@ 2014-04-22 Paul Eggert + Port to GCC 4.9.0 with --enable-gcc-warnings. + * image.c (struct my_jpeg_error_mgr) [lint]: Remove member fp. + All uses removed. + (jpeg_load_body) [lint]: Add a 'volatile' to pacify a buggy GCC in + a way that also works with GCC 4.9.0. + * search.c (Fnewline_cache_check): Remove unused locals. 2014-04-22 Eli Zaretskii diff --git a/src/image.c b/src/image.c index d6d5ace509d..4133aaa7621 100644 --- a/src/image.c +++ b/src/image.c @@ -6262,9 +6262,6 @@ struct my_jpeg_error_mgr MY_JPEG_INVALID_IMAGE_SIZE, MY_JPEG_CANNOT_CREATE_X } failure_code; -#ifdef lint - FILE *fp; -#endif }; @@ -6479,7 +6476,8 @@ jpeg_load_body (struct frame *f, struct image *img, { Lisp_Object file, specified_file; Lisp_Object specified_data; - FILE *fp = NULL; + /* The 'volatile' silences a bogus diagnostic; see GCC bug 54561. */ + FILE * IF_LINT (volatile) fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; XImagePtr ximg = NULL; @@ -6512,8 +6510,6 @@ jpeg_load_body (struct frame *f, struct image *img, return 0; } - IF_LINT (mgr->fp = fp); - /* Customize libjpeg's error handling to call my_error_exit when an error is detected. This function will perform a longjmp. */ mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub); @@ -6552,9 +6548,6 @@ jpeg_load_body (struct frame *f, struct image *img, return 0; } - /* Silence a bogus diagnostic; see GCC bug 54561. */ - IF_LINT (fp = mgr->fp); - /* Create the JPEG decompression object. Let it read from fp. Read the JPEG image header. */ fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo); -- cgit v1.2.1