diff options
| author | Glenn Morris | 2020-01-08 09:09:47 -0800 |
|---|---|---|
| committer | Glenn Morris | 2020-01-08 09:09:47 -0800 |
| commit | b968b733a2a0450eb7312a5e72c059ec3c59ddd9 (patch) | |
| tree | da0790ada823a4d7dee009e9df63b3b24d0d539b /src | |
| parent | f8a0b02949342b887822e7756fd36f06536c9c01 (diff) | |
| parent | 6cd9ccb0a28ec03ffe180b7429e0378511b7d459 (diff) | |
| download | emacs-b968b733a2a0450eb7312a5e72c059ec3c59ddd9.tar.gz emacs-b968b733a2a0450eb7312a5e72c059ec3c59ddd9.zip | |
Merge from origin/emacs-27
6cd9ccb0a2 (origin/emacs-27) Fix compression of directories in Dired
42329e6d3b ; * etc/NEWS: Review of the whole text.
af5709f16b Further enhancement on `tramp-file-local-name'
fb432446f5 Objective C Mode imenu: cease recognizing "functions" with...
a18373a999 ; * etc/NEWS: Update the text about the XDG_CONFIG_HOME/em...
73fd8a4b53 Fix BSD and macOS builds w.r.t. pthread_setname_np (bug#38...
f54b24304d Scale top-left coordinates in display-monitor-attributes-list
b46c75b16c xref-matches-in-files: Big Tramp speed-up
883b3490d8 * lisp/net/tramp.el (tramp-file-local-name): Remove `save-...
c01f55f126 Fix rendering bug due to unsynchronized cairo surface size...
075f21c0e3 Avoid crash by access to cleared img->pixmap->data/img->ma...
16c6dfb4f1 Avoid assertion violations in very small-height windows
9063124b91 Use pthread_setname_np to set thread name
# Conflicts:
# etc/NEWS
# lisp/net/tramp.el
Diffstat (limited to 'src')
| -rw-r--r-- | src/image.c | 4 | ||||
| -rw-r--r-- | src/systhread.c | 53 | ||||
| -rw-r--r-- | src/systhread.h | 5 | ||||
| -rw-r--r-- | src/thread.c | 7 | ||||
| -rw-r--r-- | src/thread.h | 3 | ||||
| -rw-r--r-- | src/xdisp.c | 28 | ||||
| -rw-r--r-- | src/xfns.c | 2 | ||||
| -rw-r--r-- | src/xterm.c | 4 |
8 files changed, 69 insertions, 37 deletions
diff --git a/src/image.c b/src/image.c index b4ce08eeb3c..d3fec37186c 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1242,6 +1242,10 @@ prepare_image_for_display (struct frame *f, struct image *img) | |||
| 1242 | if (img->cr_data == NULL || (cairo_pattern_get_type (img->cr_data) | 1242 | if (img->cr_data == NULL || (cairo_pattern_get_type (img->cr_data) |
| 1243 | != CAIRO_PATTERN_TYPE_SURFACE)) | 1243 | != CAIRO_PATTERN_TYPE_SURFACE)) |
| 1244 | { | 1244 | { |
| 1245 | /* Fill in the background/background_transparent field while | ||
| 1246 | we have img->pixmap->data/img->mask->data. */ | ||
| 1247 | IMAGE_BACKGROUND (img, f, img->pixmap); | ||
| 1248 | IMAGE_BACKGROUND_TRANSPARENT (img, f, img->mask); | ||
| 1245 | cr_put_image_to_cr_data (img); | 1249 | cr_put_image_to_cr_data (img); |
| 1246 | if (img->cr_data == NULL) | 1250 | if (img->cr_data == NULL) |
| 1247 | { | 1251 | { |
diff --git a/src/systhread.c b/src/systhread.c index c3e4e6a2c5a..2c3a060a17e 100644 --- a/src/systhread.c +++ b/src/systhread.c | |||
| @@ -98,10 +98,6 @@ sys_thread_yield (void) | |||
| 98 | 98 | ||
| 99 | #include <sched.h> | 99 | #include <sched.h> |
| 100 | 100 | ||
| 101 | #ifdef HAVE_SYS_PRCTL_H | ||
| 102 | #include <sys/prctl.h> | ||
| 103 | #endif | ||
| 104 | |||
| 105 | void | 101 | void |
| 106 | sys_mutex_init (sys_mutex_t *mutex) | 102 | sys_mutex_init (sys_mutex_t *mutex) |
| 107 | { | 103 | { |
| @@ -204,9 +200,28 @@ sys_thread_equal (sys_thread_t t, sys_thread_t u) | |||
| 204 | return pthread_equal (t, u); | 200 | return pthread_equal (t, u); |
| 205 | } | 201 | } |
| 206 | 202 | ||
| 203 | void | ||
| 204 | sys_thread_set_name (const char *name) | ||
| 205 | { | ||
| 206 | #ifdef HAVE_PTHREAD_SETNAME_NP | ||
| 207 | /* We need to truncate here otherwise pthread_setname_np | ||
| 208 | fails to set the name. TASK_COMM_LEN is what the length | ||
| 209 | is called in the Linux kernel headers (Bug#38632). */ | ||
| 210 | #define TASK_COMM_LEN 16 | ||
| 211 | char p_name[TASK_COMM_LEN]; | ||
| 212 | strncpy (p_name, name, TASK_COMM_LEN - 1); | ||
| 213 | p_name[TASK_COMM_LEN - 1] = '\0'; | ||
| 214 | #ifdef HAVE_PTHREAD_SETNAME_NP_1ARG | ||
| 215 | pthread_setname_np (p_name); | ||
| 216 | #else | ||
| 217 | pthread_setname_np (pthread_self (), p_name); | ||
| 218 | #endif | ||
| 219 | #endif | ||
| 220 | } | ||
| 221 | |||
| 207 | bool | 222 | bool |
| 208 | sys_thread_create (sys_thread_t *thread_ptr, const char *name, | 223 | sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func, |
| 209 | thread_creation_function *func, void *arg) | 224 | void *arg) |
| 210 | { | 225 | { |
| 211 | pthread_attr_t attr; | 226 | pthread_attr_t attr; |
| 212 | bool result = false; | 227 | bool result = false; |
| @@ -225,13 +240,7 @@ sys_thread_create (sys_thread_t *thread_ptr, const char *name, | |||
| 225 | } | 240 | } |
| 226 | 241 | ||
| 227 | if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED)) | 242 | if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED)) |
| 228 | { | 243 | result = pthread_create (thread_ptr, &attr, func, arg) == 0; |
| 229 | result = pthread_create (thread_ptr, &attr, func, arg) == 0; | ||
| 230 | #if defined (HAVE_SYS_PRCTL_H) && defined (HAVE_PRCTL) && defined (PR_SET_NAME) | ||
| 231 | if (result && name != NULL) | ||
| 232 | prctl (PR_SET_NAME, name); | ||
| 233 | #endif | ||
| 234 | } | ||
| 235 | 244 | ||
| 236 | out: ; | 245 | out: ; |
| 237 | int error = pthread_attr_destroy (&attr); | 246 | int error = pthread_attr_destroy (&attr); |
| @@ -452,26 +461,24 @@ w32_set_thread_name (DWORD thread_id, const char *name) | |||
| 452 | 461 | ||
| 453 | static thread_creation_function *thread_start_address; | 462 | static thread_creation_function *thread_start_address; |
| 454 | 463 | ||
| 464 | void | ||
| 465 | sys_thread_set_name (const char *name) | ||
| 466 | { | ||
| 467 | w32_set_thread_name (GetCurrentThreadId (), name); | ||
| 468 | } | ||
| 469 | |||
| 455 | /* _beginthread wants a void function, while we are passed a function | 470 | /* _beginthread wants a void function, while we are passed a function |
| 456 | that returns a pointer. So we use a wrapper. See the command in | 471 | that returns a pointer. So we use a wrapper. See the command in |
| 457 | w32term.h about the need for ALIGN_STACK attribute. */ | 472 | w32term.h about the need for ALIGN_STACK attribute. */ |
| 458 | static void ALIGN_STACK | 473 | static void ALIGN_STACK |
| 459 | w32_beginthread_wrapper (void *arg) | 474 | w32_beginthread_wrapper (void *arg) |
| 460 | { | 475 | { |
| 461 | /* FIXME: This isn't very clean: systhread.c is not supposed to know | ||
| 462 | that ARG is a pointer to a thread_state object, or be familiar | ||
| 463 | with thread_state object's structure in general. */ | ||
| 464 | struct thread_state *this_thread = arg; | ||
| 465 | |||
| 466 | if (this_thread->thread_name) | ||
| 467 | w32_set_thread_name (GetCurrentThreadId (), this_thread->thread_name); | ||
| 468 | |||
| 469 | (void)thread_start_address (arg); | 476 | (void)thread_start_address (arg); |
| 470 | } | 477 | } |
| 471 | 478 | ||
| 472 | bool | 479 | bool |
| 473 | sys_thread_create (sys_thread_t *thread_ptr, const char *name, | 480 | sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func, |
| 474 | thread_creation_function *func, void *arg) | 481 | void *arg) |
| 475 | { | 482 | { |
| 476 | /* FIXME: Do threads that run Lisp require some minimum amount of | 483 | /* FIXME: Do threads that run Lisp require some minimum amount of |
| 477 | stack? Zero here means each thread will get the same amount as | 484 | stack? Zero here means each thread will get the same amount as |
diff --git a/src/systhread.h b/src/systhread.h index 5368acfb52c..005388fd5a4 100644 --- a/src/systhread.h +++ b/src/systhread.h | |||
| @@ -112,10 +112,11 @@ extern sys_thread_t sys_thread_self (void) | |||
| 112 | extern bool sys_thread_equal (sys_thread_t, sys_thread_t) | 112 | extern bool sys_thread_equal (sys_thread_t, sys_thread_t) |
| 113 | ATTRIBUTE_WARN_UNUSED_RESULT; | 113 | ATTRIBUTE_WARN_UNUSED_RESULT; |
| 114 | 114 | ||
| 115 | extern bool sys_thread_create (sys_thread_t *, const char *, | 115 | extern bool sys_thread_create (sys_thread_t *, thread_creation_function *, |
| 116 | thread_creation_function *, void *) | 116 | void *) |
| 117 | ATTRIBUTE_WARN_UNUSED_RESULT; | 117 | ATTRIBUTE_WARN_UNUSED_RESULT; |
| 118 | 118 | ||
| 119 | extern void sys_thread_yield (void); | 119 | extern void sys_thread_yield (void); |
| 120 | extern void sys_thread_set_name (const char *); | ||
| 120 | 121 | ||
| 121 | #endif /* SYSTHREAD_H */ | 122 | #endif /* SYSTHREAD_H */ |
diff --git a/src/thread.c b/src/thread.c index f81163414bb..c7fe0614269 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -725,6 +725,9 @@ run_thread (void *state) | |||
| 725 | self->m_stack_bottom = self->stack_top = (char *) &stack_pos; | 725 | self->m_stack_bottom = self->stack_top = (char *) &stack_pos; |
| 726 | self->thread_id = sys_thread_self (); | 726 | self->thread_id = sys_thread_self (); |
| 727 | 727 | ||
| 728 | if (self->thread_name) | ||
| 729 | sys_thread_set_name (self->thread_name); | ||
| 730 | |||
| 728 | acquire_global_lock (self); | 731 | acquire_global_lock (self); |
| 729 | 732 | ||
| 730 | /* Put a dummy catcher at top-level so that handlerlist is never NULL. | 733 | /* Put a dummy catcher at top-level so that handlerlist is never NULL. |
| @@ -826,13 +829,13 @@ If NAME is given, it must be a string; it names the new thread. */) | |||
| 826 | new_thread->next_thread = all_threads; | 829 | new_thread->next_thread = all_threads; |
| 827 | all_threads = new_thread; | 830 | all_threads = new_thread; |
| 828 | 831 | ||
| 829 | char const *c_name = !NILP (name) ? SSDATA (ENCODE_UTF_8 (name)) : NULL; | 832 | char const *c_name = !NILP (name) ? SSDATA (ENCODE_SYSTEM (name)) : NULL; |
| 830 | if (c_name) | 833 | if (c_name) |
| 831 | new_thread->thread_name = xstrdup (c_name); | 834 | new_thread->thread_name = xstrdup (c_name); |
| 832 | else | 835 | else |
| 833 | new_thread->thread_name = NULL; | 836 | new_thread->thread_name = NULL; |
| 834 | sys_thread_t thr; | 837 | sys_thread_t thr; |
| 835 | if (! sys_thread_create (&thr, c_name, run_thread, new_thread)) | 838 | if (! sys_thread_create (&thr, run_thread, new_thread)) |
| 836 | { | 839 | { |
| 837 | /* Restore the previous situation. */ | 840 | /* Restore the previous situation. */ |
| 838 | all_threads = all_threads->next_thread; | 841 | all_threads = all_threads->next_thread; |
diff --git a/src/thread.h b/src/thread.h index e96a063a10b..a09929fa440 100644 --- a/src/thread.h +++ b/src/thread.h | |||
| @@ -169,8 +169,7 @@ struct thread_state | |||
| 169 | interrupter should broadcast to this condition. */ | 169 | interrupter should broadcast to this condition. */ |
| 170 | sys_cond_t *wait_condvar; | 170 | sys_cond_t *wait_condvar; |
| 171 | 171 | ||
| 172 | /* Thread's name in the locale encoding. Actually used only on | 172 | /* Thread's name in the locale encoding. */ |
| 173 | WINDOWSNT. */ | ||
| 174 | char *thread_name; | 173 | char *thread_name; |
| 175 | 174 | ||
| 176 | /* This thread might have released the global lock. If so, this is | 175 | /* This thread might have released the global lock. If so, this is |
diff --git a/src/xdisp.c b/src/xdisp.c index cc936ff179d..53300928d7b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -16244,8 +16244,8 @@ set_cursor_from_row (struct window *w, struct glyph_row *row, | |||
| 16244 | bool string_from_text_prop = false; | 16244 | bool string_from_text_prop = false; |
| 16245 | 16245 | ||
| 16246 | /* Don't even try doing anything if called for a mode-line or | 16246 | /* Don't even try doing anything if called for a mode-line or |
| 16247 | header-line row, since the rest of the code isn't prepared to | 16247 | header-line or tab-line row, since the rest of the code isn't |
| 16248 | deal with such calamities. */ | 16248 | prepared to deal with such calamities. */ |
| 16249 | eassert (!row->mode_line_p); | 16249 | eassert (!row->mode_line_p); |
| 16250 | if (row->mode_line_p) | 16250 | if (row->mode_line_p) |
| 16251 | return false; | 16251 | return false; |
| @@ -17504,6 +17504,9 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, | |||
| 17504 | else | 17504 | else |
| 17505 | { | 17505 | { |
| 17506 | row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos); | 17506 | row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos); |
| 17507 | /* Skip the tab-line and header-line rows, if any. */ | ||
| 17508 | if (row->tab_line_p) | ||
| 17509 | ++row; | ||
| 17507 | if (row->mode_line_p) | 17510 | if (row->mode_line_p) |
| 17508 | ++row; | 17511 | ++row; |
| 17509 | if (!row->enabled_p) | 17512 | if (!row->enabled_p) |
| @@ -17576,6 +17579,9 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, | |||
| 17576 | || row->mode_line_p) | 17579 | || row->mode_line_p) |
| 17577 | { | 17580 | { |
| 17578 | row = w->current_matrix->rows; | 17581 | row = w->current_matrix->rows; |
| 17582 | /* Skip the tab-line and header-line rows, if any. */ | ||
| 17583 | if (row->tab_line_p) | ||
| 17584 | ++row; | ||
| 17579 | if (row->mode_line_p) | 17585 | if (row->mode_line_p) |
| 17580 | ++row; | 17586 | ++row; |
| 17581 | } | 17587 | } |
| @@ -17640,8 +17646,9 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, | |||
| 17640 | ; | 17646 | ; |
| 17641 | else if (rc != CURSOR_MOVEMENT_SUCCESS | 17647 | else if (rc != CURSOR_MOVEMENT_SUCCESS |
| 17642 | && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) | 17648 | && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row) |
| 17643 | /* Make sure this isn't a header line by any chance, since | 17649 | /* Make sure this isn't a header line nor a tab-line by |
| 17644 | then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */ | 17650 | any chance, since then MATRIX_ROW_PARTIALLY_VISIBLE_P |
| 17651 | might yield true. */ | ||
| 17645 | && !row->mode_line_p | 17652 | && !row->mode_line_p |
| 17646 | && !cursor_row_fully_visible_p (w, true, true, true)) | 17653 | && !cursor_row_fully_visible_p (w, true, true, true)) |
| 17647 | { | 17654 | { |
| @@ -18769,11 +18776,14 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 18769 | } | 18776 | } |
| 18770 | } | 18777 | } |
| 18771 | /* Finally, fall back on the first row of the window after the | 18778 | /* Finally, fall back on the first row of the window after the |
| 18772 | header line (if any). This is slightly better than not | 18779 | tab-line and header line (if any). This is slightly better |
| 18773 | displaying the cursor at all. */ | 18780 | than not displaying the cursor at all. */ |
| 18774 | if (!row) | 18781 | if (!row) |
| 18775 | { | 18782 | { |
| 18776 | row = matrix->rows; | 18783 | row = matrix->rows; |
| 18784 | /* Skip the tab-line and header-line rows, if any. */ | ||
| 18785 | if (row->tab_line_p) | ||
| 18786 | ++row; | ||
| 18777 | if (row->mode_line_p) | 18787 | if (row->mode_line_p) |
| 18778 | ++row; | 18788 | ++row; |
| 18779 | } | 18789 | } |
| @@ -19787,7 +19797,9 @@ row_containing_pos (struct window *w, ptrdiff_t charpos, | |||
| 19787 | ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1; | 19797 | ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1; |
| 19788 | int last_y; | 19798 | int last_y; |
| 19789 | 19799 | ||
| 19790 | /* If we happen to start on a header-line, skip that. */ | 19800 | /* If we happen to start on a header-line or a tab-line, skip that. */ |
| 19801 | if (row->tab_line_p) | ||
| 19802 | ++row; | ||
| 19791 | if (row->mode_line_p) | 19803 | if (row->mode_line_p) |
| 19792 | ++row; | 19804 | ++row; |
| 19793 | 19805 | ||
| @@ -22380,7 +22392,7 @@ find_row_edges (struct it *it, struct glyph_row *row, | |||
| 22380 | if (STRINGP (it->object) | 22392 | if (STRINGP (it->object) |
| 22381 | /* this is not the first row */ | 22393 | /* this is not the first row */ |
| 22382 | && row > it->w->desired_matrix->rows | 22394 | && row > it->w->desired_matrix->rows |
| 22383 | /* previous row is not the header line */ | 22395 | /* previous row is not the header line or tab-line */ |
| 22384 | && !r1->mode_line_p | 22396 | && !r1->mode_line_p |
| 22385 | /* previous row also ends in a newline from a string */ | 22397 | /* previous row also ends in a newline from a string */ |
| 22386 | && r1->ends_in_newline_from_string_p) | 22398 | && r1->ends_in_newline_from_string_p) |
diff --git a/src/xfns.c b/src/xfns.c index d0d5d399dc4..276ea1c3935 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -5089,6 +5089,8 @@ Internal use only, use `display-monitor-attributes-list' instead. */) | |||
| 5089 | #elif defined HAVE_GTK3 | 5089 | #elif defined HAVE_GTK3 |
| 5090 | scale = gdk_screen_get_monitor_scale_factor (gscreen, i); | 5090 | scale = gdk_screen_get_monitor_scale_factor (gscreen, i); |
| 5091 | #endif | 5091 | #endif |
| 5092 | rec.x *= scale; | ||
| 5093 | rec.y *= scale; | ||
| 5092 | rec.width *= scale; | 5094 | rec.width *= scale; |
| 5093 | rec.height *= scale; | 5095 | rec.height *= scale; |
| 5094 | work.x *= scale; | 5096 | work.x *= scale; |
diff --git a/src/xterm.c b/src/xterm.c index ada3cec1636..21d99f0c7bb 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -8934,6 +8934,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8934 | if (f) | 8934 | if (f) |
| 8935 | x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width, | 8935 | x_cr_update_surface_desired_size (f, configureEvent.xconfigure.width, |
| 8936 | configureEvent.xconfigure.height); | 8936 | configureEvent.xconfigure.height); |
| 8937 | else if (any && configureEvent.xconfigure.window == FRAME_X_WINDOW (any)) | ||
| 8938 | x_cr_update_surface_desired_size (any, | ||
| 8939 | configureEvent.xconfigure.width, | ||
| 8940 | configureEvent.xconfigure.height); | ||
| 8937 | #endif | 8941 | #endif |
| 8938 | #ifdef USE_GTK | 8942 | #ifdef USE_GTK |
| 8939 | if (!f | 8943 | if (!f |