emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Emacs design and architecture. How about copy-on-write?


From: Eli Zaretskii
Subject: Re: Emacs design and architecture. How about copy-on-write?
Date: Wed, 20 Sep 2023 14:56:03 +0300

> From: Po Lu <luangruo@yahoo.com>
> Cc: acm@muc.de,  incal@dataswamp.org,  emacs-devel@gnu.org
> Date: Wed, 20 Sep 2023 09:01:56 +0800
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > So if point moves off the window, we will have a window that doesn't
> > show point?
> 
> We will have a window whose point does not reflect its contents on the
> display.  A supervening redisplay within the main thread will give due
> consideration to its new value when it does transpire.

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?

> > Yes, but almost everything we do in Emacs has its purpose of affecting
> > display, eventually.  Including process output we read and whatever
> > computations we do.  Emacs is a real-time display editor, first and
> > foremost, so this should not be a surprise.  The only notable
> > exception from this rule is batch-style execution in a script.
> 
> These eventualities must take place within the main thread, that's all.

They many times happen in the middle of processing, not just
"eventually".

> > How do you "transfer it to the main thread for display", exactly?
> 
> By setting a global variable that is subsequently read by the main
> thread, modifying unread-command-events, and signaling a condition
> variable that induces read_char to return the new value of
> unread-command-events.

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?

> > And won't you want to display some kind of progress indicator while
> > fetching? or show an error message if things fail?  Every Lisp program
> > invokes gazillion low-level subroutines and primitives, and some of
> > those feel free to ask the user questions, show messages, etc.  Even
> > process.c shows messages, and modifying a file-visiting buffer might
> > ask about supersession locks.  We cannot just forbid display from
> > non-main threads, unless we are willing to rewrite most of the
> > application code in Emacs, and many of the primitives as well.  The
> > only solution that avoids the massive rewrite is to invent mechanisms
> > that still allow non-main threads to communicate with users.
> 
> process.c can't be employed from non-main threads, as they are forbidden
> from entering wait_reading_process_output.  Likewise for the file-lock
> stuff, as it calls read_char.
> 
> My idea is that non-main threads will communicate with subprocesses and
> read or write files through a different set of primitives, but they have
> not been implemented.

Why do they have to be a different set, not the same set which is made
thread-aware?  E.g., if you don't want a primitive to do something
when it runs in a non-main thread, it is easy to write a condition for
that, and leave the rest of the code intact.

> The principle difficulty with the existing file primitives is that
> they can call thread-unsafe Lisp; file name handlers provided by
> TRAMP, for example.

Tramp should be the least of our problems.  The main problem with
refusing to run Lisp from non-main threads is that Emacs will cease to
be Emacs.  The various Lisp hooks, calls into Lisp from C, and control
on the internals exposed to Lisp are what makes Emacs the environment
that is flexible and powerful to unprecedented degree.  Take that
away, and programs written for such an "Emacs" will be much less
powerful and interesting, and certainly much less extensible.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]