From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: Date: Fri, 6 Apr 2007 09:52:30 -0400 From: "Russ Cox" To: "Fans of the OS Plan 9 from Bell Labs" <9fans@cse.psu.edu> Subject: Re: [9fans] Blocking reads on single-threaded Srv-based 9p server? In-Reply-To: <6ec892cd0704052033r3ae400e2o54bfdf447da9d994@mail.gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <6ec892cd0704052033r3ae400e2o54bfdf447da9d994@mail.gmail.com> Topicbox-Message-UUID: 402ac4dc-ead2-11e9-9d60-3106f5b1d025 On 4/5/07, Colin DeVilbiss wrote: > I'm implementing a 9p server using plan9port. > > I'd like one of my files to have "blocking read" or "blocking write" > behavior: any such call should block until a write occurs on some > other (non-blocking) file in the same server. This is perfectly fine to do in a single-threaded server. You need to implement flush to make sure that clients don't get hung up indefinitely. > Is there some reason that I shouldn't implement that in a > single-threaded server? The 9p(3) plan9ports manpage suggests that > only multi-threaded servers should "block" requests by not > respond()ing to them before returning from the associated service > routine, and that only multi-threaded servers would need to implement > flush(). The text is admittedly misleading. I removed mention of single vs multi-threaded programs. The real issue is whether requests are always replied to before returning from the Srv function. If so, no need for flush. If not (which is okay), you need to provide a flush. > My plan: > In my Srv's read() (or write()) routine, if a Req comes in for > that file and I decide that it should block, I save it off somewhere > and don't respond() to it. > In my write() routine, if a "should unblock any waiters" event > occurs, go find all of the associated "saved" Req's and respond() to > them all. > Implement a flush() routine that "un-saves" the oldreq and > responds with "interrupted" (per the manpage). This is perfectly fine to do in a single-threaded program and is very common. Aux/consolefs does it (without lib9p), and the p9p auth/factotum/log.c implements a one-sided variant of it for reading from the event log. > As a side note, I see that none of the 9p filesystems that are > currently packaged in plan9port are both single-threaded and > Srv-based. Is there some reason I don't want to do that here? P9p's lib9p requires libthread in order to create new processes. (If someone ever ports p9p to Windows, they'll be happy that libthread's interface is the only one used to start new programs instead of widespread use of fork+exec.) That doesn't mean your program has to be multithreaded. You can write single-threaded libthread programs. Russ