From mboxrd@z Thu Jan 1 00:00:00 1970 MIME-Version: 1.0 In-Reply-To: <53efcb3de52d8327fb42f54b6a5a1c08@felloff.net> References: <53efcb3de52d8327fb42f54b6a5a1c08@felloff.net> Date: Wed, 3 Feb 2016 09:53:04 -0200 Message-ID: From: Tiago Natel To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> Content-Type: multipart/alternative; boundary=001a1140d744c718b8052adc4258 Subject: Re: [9fans] Fwd: lib9p: Add clunk callback to Srv struct Topicbox-Message-UUID: 820ed22e-ead9-11e9-9d60-3106f5b1d025 --001a1140d744c718b8052adc4258 Content-Type: text/plain; charset=UTF-8 2016-02-02 23:25 GMT-02:00 : > > > It is hard to say without seeing the code, but this construction sounds > wrong > as recvp() in Srv.read would block the 9p read loop causing you to > not process any other 9p requests when one client is blocked in a read. > You also want to handle flushes otherwise you cannot interrupt/cancel > the blocked read. You can handle this by chaining the Req's that you > cannot satisfy immidiately in a linked list and respond to them from some > other proc or thread once you have data the client could read. > Source code: hg clone https://bitbucket.org/tiago4orion/dchan Well, I'm doing a lot of tests with simultaneous access and everything 'appears' to works as expected. I'm using threadlistensrv/threadpostmountsrv to handle each new 9P connection in a separate thread. When a new client creates a file, the file server creates a Channel and two additional threads (one for block the reads, and one for block the writes) that will enqueue (reqqueuepush) the related requests. See here: Create a new file (or dchan channel): fs.c:497,507 When someone attempts to write to this file: fs.c:/^fswrite The request will be enqueued in the f->aux->wq (Reqqueue*) executing the function syncwrite on the writer thread of this file. The fs.c:/^syncwrite will send the r->ifcall.data in the channel associated with the file (f->aux->chan) and it will block the writer thread (of this specific file) until someother 9P client attempts to read the file. The read is similar, but happens in the syncread function. That way I'm able to create multiple clients: plan9: cpu% mount -c /srv/dchan /n/dchan Linux: # mount -t 9p -o port=6666 ip.of.dchan /n/dchan # cd /n/dchan # touch pipeline The command above will create two associated with this specific file. # cat pipeline The command above will block in the recvp call in the reader thread of this file, until someone writes something in it. cpu% cd /n/dchan cpu% ls ctl stats pipeline cpu% echo AAAAAAAAAAAAA >> pipeline The command above will issue a sendp in the same channel on the writer thread. The linux box will receive (recvp) the data and block in the next read(2). That's the workflow. > > What do you mean by client? By client I mean a 9P connection: mount -c /srv/dchan /n/dchan > You could have multiple Srv's with each > client having its own network connection to it. I'm using thread*srv function to achieve this. It's correct, isn't? > Or it could mean multiple > attaches (mounts) and a single Srv. Or you it could mean you mean *someone* > reading the file and the state about a "Client" is in the Fid. Anyway, > it sounds like the problem you'r having with destroyfid() is that it doenst > give you access to information whoever is the client of the file closed no? > Yes, I don't know if I understodd what you mean, but yeah, I need the information when someone closed the file (stopped reading the Channel). Thanks > > -- > cinap > > --001a1140d744c718b8052adc4258 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
2016= -02-02 23:25 GMT-02:00 <cinap_lenrek@felloff.net>:
It is hard to say without seeing the code, but this construction sou= nds wrong
as recvp() in Srv.read would block the 9p read loop causing you to
not process any other 9p requests when one client is blocked in a read.
You also want to handle flushes otherwise you cannot interrupt/cancel
the blocked read. You can handle this by chaining the Req's that you cannot satisfy immidiately in a linked list and respond to them from some other proc or thread once you have data the client could read.

=C2=A0Source code: hg clone https://bitbucket.org/tiago4orion/dchan

Well, I'm doing a lot of tests with simultaneous= access and everything 'appears' to works as expected.
I&= #39;m using threadlistensrv/threadpostmountsrv to handle each new 9P connec= tion in a separate thread.

When a new client creat= es a file, the file server creates a Channel and two additional threads (on= e for block the reads, and one for block the writes) that will enqueue (req= queuepush) the related requests. See here:

Create = a new file (or dchan channel): fs.c:497,507

When s= omeone attempts to write to this file: fs.c:/^fswrite
The request= will be enqueued in the f->aux->wq (Reqqueue*) executing the functio= n syncwrite on the writer thread of this file.

The= fs.c:/^syncwrite will send the r->ifcall.data in the channel associated= with the file (f->aux->chan) and it will block the writer thread (of= this specific file) until someother 9P client attempts to read the file. T= he read is similar, but happens in the syncread function.

That way I'm able to create multiple clients:

plan9:
cpu% mount -c /srv/dchan /n/dchan

Linux:
# mount -t 9p -o port=3D6666 ip.of.dchan /n/dchan=

# cd /n/dchan
# touch pipeline
The command above will create two associated with this specific file.

# cat pipeline
The command above will block= in the recvp call in the reader thread of this file, until someone writes = something in it.

cpu% cd /n/dchan
cpu% l= s
ctl stats pipeline
cpu% echo AAAAAAAAAAAAA >> p= ipeline

The command above will issue a sendp in th= e same channel on the writer thread. The linux box will receive (recvp) the= data and block in the next read(2).

That's th= e workflow.

What do you mean by client?

By client I me= an a 9P connection: mount -c /srv/dchan /n/dchan
=C2=A0
You could have multiple Srv's with each
client having its own network connection to it.

I'm using thread*srv function to achieve this. It's correct, = isn't?
=C2=A0
Or it could mean multiple=
attaches (mounts) and a single Srv. Or you it could mean you mean *someone*=
reading the file and the state about a "Client" is in the Fid. An= yway,
it sounds like the problem you'r having with destroyfid() is that it do= enst
give you access to information whoever is the client of the file closed no?=

=C2=A0Yes, I don't know if I under= stodd what you mean, but yeah, I need the information when someone closed t= he file (stopped reading the Channel).

Thanks

--
cinap


--001a1140d744c718b8052adc4258--