Eli Zaretskii <address@hidden
> schrieb am Sa., 22. Apr. 2017 um 22:13 Uhr:
> From: Philipp Stephani <address@hidden>
> Date: Sat, 22 Apr 2017 20:05:19 +0000
> Cc: address@hidden, address@hidden
> I agree that checking for the main thread is not TRT, but why not
> allow any thread of those in all_threads? Why do we care that the env
> pointer was created by the same thread as the one using it? We should
> only care that the invoking thread is one of the Emacs application
> threads, no?
> - Using objects across threads requires careful synchronization.
Not sure what synchronization you have in mind. There's only one
running thread at any given time, and a thread cannot be preempted
while it runs Lisp, so synchronization seems unnecessary, as a thread
cannot modify a Lisp object that another thread is modifying.
However, that's just an implementation detail, and the mapping between Emacs and OS threads is unspecified (for good reason). To be forward-compatible, either we have to formally document this and then never ever change the implementation, or document that module authors can't rely on it and have to perform synchronization themselves.
> - The more restrictive the module API is, the more freedom we have in the implementation.
I don't think I understand this. From my POV, restricting modules to
be called only from one thread is too restrictive, and I see no reason
I meant this as a general statement: if an API is more restrictive (i.e. has stronger preconditions), its implementation can be more flexible because it has to deal with fewer corner cases.
Specifically, the modules API is definitely not intended to restrict modules to be single-threaded. It only restricts under which circumstances environments can be used: the lifetime is restricted to the storage duration of the environment pointer, and this patch adds an additional restriction that environments are thread-affine.
> - The current check is easy to implement and understand. A check for multiple threads would require another
> hash table with thread IDs etc.
Why do you need a has table? There's a linked list in all_threads
which holds all the known application threads, we just need a loop
I think I misunderstood what would be needed to implement this check; in fact, it's already implemented in this patch:
assert (current_thread->thread_id == pthread_self());
Note that it's not enough to check whether the current OS thread matches *some* Emacs thread, it has to be *the current* Emacs thread, otherwise the interpreter state is inconsistent.
> - The Emacs module API is modelled after JNI, which has the same restriction
Themodule API is modelled after JNI, but the threads model is a far
cry from Java threads. So I don't think this argument is relevant,
unless you can show specific problems with our implementation of
It's generally not possible to show specific problems because there is not enough experience with the combination of multithreading and modules. Also, thread synchronization problems (data races) typically lead to subtle undefined behavior, which isn't easily observed.
By contrast, there's lots of experience with JNI, and it makes sense to base a new design on an existing design.