From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: David Kastrup Newsgroups: gmane.emacs.devel Subject: Re: Tramp with global-auto-revert-mode. Date: 15 May 2004 19:01:24 +0200 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: References: <200405122254.i4CMsUj29445@raven.dms.auburn.edu> <200405122326.i4CNQk929511@raven.dms.auburn.edu> <200405132324.i4DNOBs14811@raven.dms.auburn.edu> <200405140008.i4E08lb14858@raven.dms.auburn.edu> <871xln4xmc.fsf-monnier+emacs@gnu.org> <87oeorb5pq.fsf@emptyhost.emptydomain.de> <863c62kai6.fsf@slowfox.dyndns.org> <86wu3d7jel.fsf@slowfox.dyndns.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1084640807 4398 80.91.224.253 (15 May 2004 17:06:47 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sat, 15 May 2004 17:06:47 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Sat May 15 19:06:39 2004 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BP2cR-0003sg-00 for ; Sat, 15 May 2004 19:06:39 +0200 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1BP2cR-00072l-00 for ; Sat, 15 May 2004 19:06:39 +0200 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.34) id 1BP2aH-000261-6O for emacs-devel@quimby.gnus.org; Sat, 15 May 2004 13:04:25 -0400 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.34) id 1BP2Zf-0001wJ-DS for emacs-devel@gnu.org; Sat, 15 May 2004 13:03:47 -0400 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.34) id 1BP2Z6-00016q-Mk for emacs-devel@gnu.org; Sat, 15 May 2004 13:03:44 -0400 Original-Received: from [199.232.76.164] (helo=fencepost.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.34) id 1BP2XP-0000Lb-9E for emacs-devel@gnu.org; Sat, 15 May 2004 13:01:27 -0400 Original-Received: from localhost ([127.0.0.1] helo=lola.goethe.zz) by fencepost.gnu.org with esmtp (Exim 4.34) id 1BP2XO-0007Vm-AU; Sat, 15 May 2004 13:01:27 -0400 Original-To: Kai Grossjohann In-Reply-To: <86wu3d7jel.fsf@slowfox.dyndns.org> User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50 Original-Lines: 118 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.4 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:23489 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:23489 Kai Grossjohann writes: > David Kastrup writes: > > > Uh, much too complicated. > > I'm afraid I don't understand you: Do you mean that just the last > step is too complicated, or that the whole procedure that I described > is too complicated? The whole procedure. > At some point, I thought I understood what you were suggesting, but > now I'm not sure anymore. > > Let me try to describe my understanding with less detail, then please > tell me if I got it at least at this level. > > Whenever Tramp is invoked, it looks to see if the connection > buffer is busy. If it is, it knows that Tramp is interrupting > itself, so to speak. > > If this is the case (Tramp is interrupting itself), Tramp "takes > over" the command in progress, fetches all output from it and > stashes it someplace safe. Look, you are talking all the time about "Tramp" as if it was a sentient being. It isn't. "Tramp" consists of two entirely different pieces: the user level routines (of which several can be running at once in different "threads" or Emacs' equivalence to it) and the filter routine. Those are basically independent from each other. In order avoid unnecessary lockup in process-send-string, and problems with identifying responses and input, we might not just indiscriminately call process-send-string when there are already outstanding commands. Ok, here is what the filter routine does when it is called: it collects the stuff from the output until it has a completely reply to the currently sent command available. If it has, it takes the request and marks it as completed (tacking the results to the request). [Entry point for getting a command on the way:] It then takes a look whether there are still outstanding commands in the queue. If there are, it takes the next one from the queue and sends it through, marking it as being in progress. That's all. The filter routine never changes, it does just that. There is only one filter routine at work at most at any time. Now for the user level stuff: it knows it needs to get commands through. So it makes a request data structure and tacks it to the end of the current queue (or, if the command is particularly urgent, like when we are doing autorevert checking, to the _front_ of the current queue) and then calls accept-process-output on the process repeatedly until the command finally is marked as being processed. Then it takes the results and returns. That is all. > Then it does its own thing. > > Afterwards, it gets the output from the safe place, inserts it > into the connection buffer, and makes it appear to the > "interrupted" "master" Tramp as if nothing had happened in the > meantime. > > You were also talking about a queue of commands, which I'm not > seeing. So this would be an indication that I misunderstood you. Probably. You don't just want to stuff the pipe with process-send-string indiscriminately, it may stall at one time, and then a different thread might feel tempted to stuff its material right in the wrong place. So at any time, at most one thread may be allowed to send strings. If there is already a reason for the filter routine to run (because some command is in the process of being transmitted), then the requesting process will _not_ write to the tty, but meekly queue his request into a request queue and hope that the filter routine will at some time be friendly enough to process it. > (The above does imply a stack of commands, corresponding to > interruptions of interruptions.) Quite. Since Emacs does not have true concurrency, "deeper" commands in the "user stack" will not get resumed or finished until "higher" commands are completed. Which they eventually will, since the filter routine will cater for everything in the queue. For stuff like autorevert it would be a good idea to check whether the queue already contains some request for the same thing. If it does, no need to add another one. Similar things hold for fetching a particular directory into the directory buffer, although here the resulting information _is_ needed, so one needs to call accept-process-output until the information has arrived, even though it was requested by a different thread/layer/task/whatyouwantocallit. > > When output arrives, the currently active filter function will be > > called with it and _all_ accept-process-output calling threads > > will get woken up again. So they will need to check whether their > > respective work has already been done or aborted by the filter > > routine. > > Hm. If more than one thread of execution will be woken up at the > same time, then surely the above procedure won't work. Emacs can't do anything "at the same time". We don't have concurrency. It has a stack of outstanding commands started from the main loop (and a list of things it may call from the main loop). It works this stack off top to bottom. Even if Emacs had separate stacks for the main loops, it would not schedule between them except when control is explicitly yielded (can happen with I/O). -- David Kastrup, Kriemhildstr. 15, 44793 Bochum