|
From: | Dmitry Gutov |
Subject: | Re: Emacs design and architecture. How about copy-on-write? |
Date: | Wed, 20 Sep 2023 21:50:59 +0300 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.13.0 |
On 20/09/2023 15:13, Po Lu wrote:
Eli Zaretskii<eliz@gnu.org> writes:I don't understand why only the main thread is allowed to do that. What is special in the main thread wrt redisplay that other threads are forbidden from doing that? Would it be okay to have a separate non-main redisplay thread, for example? if not, why not?Because toolkits forbid that. One thread is customarily designated the ``main'' thread when the toolkit is initialized, after which any attempt to invoke display routines from another thread induces a prompt abort. This manifests itself most severely on NS and both GTK builds.
Could the "main thread" which works on the level of toolkits be/become a distinct notion from the "main Lisp thread"?
They many times happen in the middle of processing, not just "eventually".Then the text written to the glass will be inconsistent as long as redisplay transpires while processing is still taking place. Averting such situations is not within our purview, but that of authors writing Lisp code that exploits threads.How is this different from telling the main thread to stop, and then doing the display from the thread which triggered that? IOW, why do we need to ask the main thread to actually display (and perform input), as opposed to just get out of the way for a short while?Even with the toolkit problem notwithstanding, we would still have to wait for the main thread to enter a section of code where it becomes safe to yield to a second thread. The main thread would then be hung until any number of other threads complete redisplay, which IMNSHO eliminates the raison d'etre for running multiple threads concurrently. And there must be some other reason no other extant programs have adopted such an approach.
I would imagine (if we do get concurrent threads) that the UI thread might work like this: enumerate the visible buffers, "lock" each of the visible ones and then run redisplay on them. What's not-obvious is how to fit in the Lisp callbacks that are required in each of those by redisplay, especially, if some of the buffers are locked by non-default threads.
At the moment (IIUC) this just looks like recursive calls because any redisplay is triggered by the main thread. And the above scheme would require running Lisp in a buffer which is locked by the thread different from the one that triggered redisplay.
Though perhaps redisplay wouldn't be triggered by threads at all - not often, anyway. A thread could send a "request for redisplay" (if it needs to call something like 'redisplay' or 'posn-at-point'), at which point it might get suspended until the "display thread" gets to it. Then, if required, the thread runs any additional Lisp which is necessary to redisplay the current buffer. This could make those calls slower, but only experience would show by how much. If a Lisp thread doesn't really ask for redisplay, it could still be suspended by the "display thread" to do its thing. Could it run the necessary Lisp code on the suspended Lisp thread, though?
[Prev in Thread] | Current Thread | [Next in Thread] |