diff options
| author | Tom Tromey | 2013-06-06 13:18:05 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-06-06 13:18:05 -0600 |
| commit | 313dfb6277b3e1ef28c7bb76e776f10168e3f0a3 (patch) | |
| tree | d1028baf9549ea7342410ae76a41cdb67008f2b4 /src | |
| parent | ac70709c2ad3fa97e7553adfb4958c0a08faa40b (diff) | |
| download | emacs-313dfb6277b3e1ef28c7bb76e776f10168e3f0a3.tar.gz emacs-313dfb6277b3e1ef28c7bb76e776f10168e3f0a3.zip | |
fix a few latent issues in the thread patch
* we called unbind_for_thread_switch unconditionally, but this
is wrong if the previous thread exited
* likewise, exiting a thread should clear current_thread
* redundant assignment in run_thread
* clean up init_threads - no need to re-init the primary thread
This patch still sometimes causes weird hangs in "make check".
However, I think that is a kernel bug, since Emacs enters the zombie
state but its parent process hangs in wait. This shouldn't happen.
Diffstat (limited to 'src')
| -rw-r--r-- | src/thread.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/thread.c b/src/thread.c index 1d282c3557a..8f58faf1b08 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -52,7 +52,11 @@ post_acquire_global_lock (struct thread_state *self) | |||
| 52 | 52 | ||
| 53 | if (self != current_thread) | 53 | if (self != current_thread) |
| 54 | { | 54 | { |
| 55 | unbind_for_thread_switch (); | 55 | /* CURRENT_THREAD is NULL if the previously current thread |
| 56 | exited. In this case, there is no reason to unbind, and | ||
| 57 | trying will crash. */ | ||
| 58 | if (current_thread != NULL) | ||
| 59 | unbind_for_thread_switch (); | ||
| 56 | current_thread = self; | 60 | current_thread = self; |
| 57 | rebind_for_thread_switch (); | 61 | rebind_for_thread_switch (); |
| 58 | } | 62 | } |
| @@ -625,7 +629,7 @@ run_thread (void *state) | |||
| 625 | struct thread_state **iter; | 629 | struct thread_state **iter; |
| 626 | 630 | ||
| 627 | self->m_stack_bottom = &stack_pos; | 631 | self->m_stack_bottom = &stack_pos; |
| 628 | self->stack_top = self->m_stack_bottom = &stack_pos; | 632 | self->stack_top = &stack_pos; |
| 629 | self->thread_id = sys_thread_self (); | 633 | self->thread_id = sys_thread_self (); |
| 630 | 634 | ||
| 631 | acquire_global_lock (self); | 635 | acquire_global_lock (self); |
| @@ -653,6 +657,7 @@ run_thread (void *state) | |||
| 653 | self->m_specpdl_ptr = NULL; | 657 | self->m_specpdl_ptr = NULL; |
| 654 | self->m_specpdl_size = 0; | 658 | self->m_specpdl_size = 0; |
| 655 | 659 | ||
| 660 | current_thread = NULL; | ||
| 656 | sys_cond_broadcast (&self->thread_condvar); | 661 | sys_cond_broadcast (&self->thread_condvar); |
| 657 | 662 | ||
| 658 | release_global_lock (); | 663 | release_global_lock (); |
| @@ -905,8 +910,6 @@ init_primary_thread (void) | |||
| 905 | primary_thread.error_symbol = Qnil; | 910 | primary_thread.error_symbol = Qnil; |
| 906 | primary_thread.error_data = Qnil; | 911 | primary_thread.error_data = Qnil; |
| 907 | primary_thread.event_object = Qnil; | 912 | primary_thread.event_object = Qnil; |
| 908 | |||
| 909 | sys_cond_init (&primary_thread.thread_condvar); | ||
| 910 | } | 913 | } |
| 911 | 914 | ||
| 912 | void | 915 | void |
| @@ -918,10 +921,11 @@ init_threads_once (void) | |||
| 918 | void | 921 | void |
| 919 | init_threads (void) | 922 | init_threads (void) |
| 920 | { | 923 | { |
| 921 | init_primary_thread (); | 924 | sys_cond_init (&primary_thread.thread_condvar); |
| 922 | |||
| 923 | sys_mutex_init (&global_lock); | 925 | sys_mutex_init (&global_lock); |
| 924 | sys_mutex_lock (&global_lock); | 926 | sys_mutex_lock (&global_lock); |
| 927 | current_thread = &primary_thread; | ||
| 928 | primary_thread.thread_id = sys_thread_self (); | ||
| 925 | } | 929 | } |
| 926 | 930 | ||
| 927 | void | 931 | void |