aboutsummaryrefslogtreecommitdiffstats
path: root/src/thread.c
diff options
context:
space:
mode:
authorPo Lu2024-02-06 17:52:33 +0800
committerPo Lu2024-02-06 17:53:23 +0800
commit42db7292c3e05920bc9f2fa5c3478eb2ba835c5c (patch)
tree7683bc7a9595f48734b43e5ee6c0eac660fdc39a /src/thread.c
parent0d2b7120783255fbb0f8e98717573c35425f4df6 (diff)
downloademacs-42db7292c3e05920bc9f2fa5c3478eb2ba835c5c.tar.gz
emacs-42db7292c3e05920bc9f2fa5c3478eb2ba835c5c.zip
Implement Lisp threading on Android
Much like the NS port, only the main thread receives input from the user interface, which is fortunately not a major problem for packages such as lsp-mode that create Lisp threads. * configure.ac: Enable with_threads under Android. * src/android.c (android_init_events): Set `main_thread_id' to the ID of the main thread. (setEmacsParams): Set new global variable `android_jvm' to the JVM object, for the purpose of attaching Lisp threads to the JVM. (android_select): [THREADS_ENABLED]: If the caller isn't the main thread, resort to pselect. Don't check query before select returns. (android_check_query): Export. * src/android.h (_ANDROID_H_): Define new macro and update prototypes. * src/process.c (android_select_wrapper): New function. (wait_reading_process_output): If THREADS_ENABLED, call thread_select through the Android select wrapper. * src/thread.c (post_acquire_global_lock): Call android_check_query; replace android_java_env with the incoming Lisp thread's. (run_thread): Attach and detach the thread created to the JVM. (init_threads): Set the main thread's JNI environment object. * src/thread.h (struct thread_state) <java_env>: New field.
Diffstat (limited to 'src/thread.c')
-rw-r--r--src/thread.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/thread.c b/src/thread.c
index 040ca39511e..2f5d7a08838 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -106,6 +106,12 @@ post_acquire_global_lock (struct thread_state *self)
106{ 106{
107 struct thread_state *prev_thread = current_thread; 107 struct thread_state *prev_thread = current_thread;
108 108
109 /* Switch the JNI interface pointer to the environment assigned to the
110 current thread. */
111#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
112 android_java_env = self->java_env;
113#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
114
109 /* Do this early on, so that code below could signal errors (e.g., 115 /* Do this early on, so that code below could signal errors (e.g.,
110 unbind_for_thread_switch might) correctly, because we are already 116 unbind_for_thread_switch might) correctly, because we are already
111 running in the context of the thread pointed by SELF. */ 117 running in the context of the thread pointed by SELF. */
@@ -126,6 +132,12 @@ post_acquire_global_lock (struct thread_state *self)
126 set_buffer_internal_2 (current_buffer); 132 set_buffer_internal_2 (current_buffer);
127 } 133 }
128 134
135#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
136 /* This step is performed in android_select when built without
137 threads. */
138 android_check_query ();
139#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
140
129 /* We could have been signaled while waiting to grab the global lock 141 /* We could have been signaled while waiting to grab the global lock
130 for the first time since this thread was created, in which case 142 for the first time since this thread was created, in which case
131 we didn't yet have the opportunity to set up the handlers. Delay 143 we didn't yet have the opportunity to set up the handlers. Delay
@@ -756,6 +768,11 @@ run_thread (void *state)
756 768
757 struct thread_state *self = state; 769 struct thread_state *self = state;
758 struct thread_state **iter; 770 struct thread_state **iter;
771#ifdef THREADS_ENABLED
772#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
773 jint rc;
774#endif /* #if defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
775#endif /* THREADS_ENABLED */
759 776
760#ifdef HAVE_NS 777#ifdef HAVE_NS
761 /* Allocate an autorelease pool in case this thread calls any 778 /* Allocate an autorelease pool in case this thread calls any
@@ -766,6 +783,16 @@ run_thread (void *state)
766 void *pool = ns_alloc_autorelease_pool (); 783 void *pool = ns_alloc_autorelease_pool ();
767#endif 784#endif
768 785
786#ifdef THREADS_ENABLED
787#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
788 rc
789 = (*android_jvm)->AttachCurrentThread (android_jvm, &self->java_env,
790 NULL);
791 if (rc != JNI_OK)
792 emacs_abort ();
793#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
794#endif /* THREADS_ENABLED */
795
769 self->m_stack_bottom = self->stack_top = &stack_pos.c; 796 self->m_stack_bottom = self->stack_top = &stack_pos.c;
770 self->thread_id = sys_thread_self (); 797 self->thread_id = sys_thread_self ();
771 798
@@ -812,6 +839,14 @@ run_thread (void *state)
812 ns_release_autorelease_pool (pool); 839 ns_release_autorelease_pool (pool);
813#endif 840#endif
814 841
842#ifdef THREADS_ENABLED
843#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
844 rc = (*android_jvm)->DetachCurrentThread (android_jvm);
845 if (rc != JNI_OK)
846 emacs_abort ();
847#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
848#endif /* THREADS_ENABLED */
849
815 /* Unlink this thread from the list of all threads. Note that we 850 /* Unlink this thread from the list of all threads. Note that we
816 have to do this very late, after broadcasting our death. 851 have to do this very late, after broadcasting our death.
817 Otherwise the GC may decide to reap the thread_state object, 852 Otherwise the GC may decide to reap the thread_state object,
@@ -1131,6 +1166,10 @@ init_threads (void)
1131 sys_mutex_init (&global_lock); 1166 sys_mutex_init (&global_lock);
1132 sys_mutex_lock (&global_lock); 1167 sys_mutex_lock (&global_lock);
1133 current_thread = &main_thread.s; 1168 current_thread = &main_thread.s;
1169#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
1170 current_thread->java_env = android_java_env;
1171#endif /* defined HAVE_ANDROID && !defined ANDROID_STUBIFY */
1172
1134 main_thread.s.thread_id = sys_thread_self (); 1173 main_thread.s.thread_id = sys_thread_self ();
1135 init_bc_thread (&main_thread.s.bc); 1174 init_bc_thread (&main_thread.s.bc);
1136} 1175}