Re: [Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes

2005-11-18 Thread Dmitry Adamushko

[EMAIL PROTECTED] wrote on 18.11.2005 09:57:15:

 
 Exactly, I have just found out that and posted actually a long mail just 
 before getting this mail from you :o)
 
 Yep, and before getting blocked, read() increments the counter as 
 well, that's 
 why we don't have a xnpipe_realease() called as a result of close().
 So everything is correct.
  
 
 Fine. Though then my problem is not related to xenomai, any suggestions
 on how to force read() to return? (without writing anything to the other
 end of the pipe)

ummm... send it a certain signal with pthread_kill() (and setting up something like thread::flag == END_OF_WORK_BABY at the same time but only in case when there can be other cases of getting a signal by this thread)? In such a case, read() should return -EINTR.
Note, a signal handler must be installed without a SA_RESTART flag so that the read() will not be restarted after signal processing.


---

Dmitry
___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


[Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes

2005-11-18 Thread Ignacio García Pérez

Exactly, I have just found out that and posted actually a long mail just 
before getting this mail from you :o)

Yep, and before getting blocked, read() increments the counter as well, that's 
why we don't have a xnpipe_realease() called as a result of close().
So everything is correct.
  

Fine. Though then my problem is not related to xenomai, any suggestions
on how to force read() to return? (without writing anything to the other
end of the pipe)



[Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes

2005-11-17 Thread Dmitry Adamushko
On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote:
 Dmitry Adamushko wrote:
As a conclusion, the behaviour that you observed with Xenomai
pipes seems consistent with that of Linux' named pipes, except
that in Linux read() returns 0, and not an error code as you
observed with Xenomai.
   
The read() call does *not* return when you close the *same* file
handle from another pthread in the same process.
  
   I confirm that and as I pointed it out in my previous mail - this is not
   how it's supposed to be.
   I'm currently on it. More news later.

 I am not sure about that: Linux regular pipes follow the same behaviour
 (the real destruction of the file descriptor is delayed until read()
 really returns).

My assertion was only based on the idea that nucleus::xnpipe_release() must be 
called as a result of any close() from the user space. And it, in turn, wakes 
up all the blocked readers. So the current implementation at least should 
have worked in sych a case. But, well, below is what I have observed.

Maybe your assertion may explain that.

The reason is actually not because of some problem in the xenomai codebase but 
because of the fact that nucleus::xnpipe_release() is _not_ called as I 
expected it to be :o)

The experiment was as follows (a slightly changed klatency test):

latency_module.ko uses a 10-second wait-interval for sending data

int fd; // pipe

thread#2
{
sleep(3);
close(fd); 

// closing a pipe. Here I expected that nucleus::xnpipe_release() would be 
// called as a result (== file_operations::release ).
}

thread#1
{
fd = open(/dev/rtpN);

pthread_create(thread#2);

read(fd, ...);  // blocked at least for 10 seconds so thread#2 closes a pipe 
//earlier 

...
if (error)
break;

...
close(fd);
}

So xnpipe_release() is _not_ called as a result of the close() call in 
thread#2. close() returns 0 indeed.

10 seconds after its starting, thread#1 :: read() returns a valid block of 
data from the latency module and right after that - an error code is returned 
that the pipe is no longer valid.

I have taken a very brief look at the linux sources but it was not enough to 
get an explanation. So I'll take a closer look now :o)


---

Dmitry





[Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes

2005-11-17 Thread Gilles Chanteperdrix
Dmitry Adamushko wrote:
  On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote:
   Dmitry Adamushko wrote:
  As a conclusion, the behaviour that you observed with Xenomai
  pipes seems consistent with that of Linux' named pipes, except
  that in Linux read() returns 0, and not an error code as you
  observed with Xenomai.
 
  The read() call does *not* return when you close the *same* file
  handle from another pthread in the same process.

 I confirm that and as I pointed it out in my previous mail - this is not
 how it's supposed to be.
 I'm currently on it. More news later.
  
   I am not sure about that: Linux regular pipes follow the same behaviour
   (the real destruction of the file descriptor is delayed until read()
   really returns).
  
  My assertion was only based on the idea that nucleus::xnpipe_release() must 
  be 

  called as a result of any close() from the user space.

If we have a look at the sources, sys_read uses fput_light and
fget_light, which increment and decrement the file descriptor
reference count (member f_count of the file structure) used by fget and
fput when the file descriptor is shared between. open and close call
fget and fput.

release only get called through __fput when f_count reaches 0.

-- 


Gilles Chanteperdrix.



[Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes

2005-11-17 Thread Dmitry Adamushko
On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote:
 Dmitry Adamushko wrote:
As a conclusion, the behaviour that you observed with Xenomai
pipes seems consistent with that of Linux' named pipes, except
that in Linux read() returns 0, and not an error code as you
observed with Xenomai.
   
The read() call does *not* return when you close the *same* file
handle from another pthread in the same process.
  
   I confirm that and as I pointed it out in my previous mail - this is not
   how it's supposed to be.
   I'm currently on it. More news later.

 I am not sure about that: Linux regular pipes follow the same behaviour
 (the real destruction of the file descriptor is delayed until read()
 really returns).

Ok, it's me who is a stupid uneducated zorr... I mean bozzo :o)

The reason is quite simple indeed.

The file_operations::release() is called when a file * object is about to be 
destroyed (file * object is created for each open file). It happens when its 
refference count becomes 0.

Rigth after open() the counter == 1. As one may guess, close() decrease it on 
1.

There is another entity - file_operations::flush() which is called on each 
close() call. But file_operations::release() is called only when all the 
references on the object have been closed.

There can be N:1 relation. Imagine, dup() or fork() make a copy of the file 
descriptor and as a result - the regerence is increased appropriately.

Now what happens is that read/write() calls increase the counter before using 
a file object and decrease it right before returning.


thread1::open() -- file_operations::open() == xnpipe_open()   --- counter=1

thread1::read() -- ... counter=2 .. - file_operations::read() == 
xnpipe_read() - blocked ... (*)

thread2::close() -- ... - file_operations::flush() [ we don't make use of 
this one in pipe.c ] -- counter = 1

So that's why xnpipe_release() is not called!

10 seconds have elapsed

thread1::read (*) - unblocked() -- copies data to the user's buffer --- 
counter = 0. Oooops!

As a result - file_operations::release() is called! Next thread1::read() call 
returns an error code.

So that's what happens. We can define file_operations::flush() and wake up all 
the readers there. But we can't know that this is a last reference on the 
file (ok, we can actually but with a bit of hacking).
I mean :

f = open() - 1 reference
f2 = dup(f)- the 2-nd

close(f);
close(f2);

2 flush() calls but only 1 release() so do we need to wake up all the readers 
if the file is still valid?

So well, at least, there is no problem with the xenomai codebase, that's 
good :o)


---

Dmitry

 






[Xenomai-core] Re: [Xenomai-help] Blocking reads from pipes

2005-11-17 Thread Dmitry Adamushko
On Thursday 17 November 2005 20:17, you wrote:
 Dmitry Adamushko wrote:
   On Thursday 17 November 2005 18:24, Gilles Chanteperdrix wrote:
Dmitry Adamushko wrote:
   As a conclusion, the behaviour that you observed with Xenomai
   pipes seems consistent with that of Linux' named pipes, except
   that in Linux read() returns 0, and not an error code as you
   observed with Xenomai.
  
   The read() call does *not* return when you close the *same* file
   handle from another pthread in the same process.
 
  I confirm that and as I pointed it out in my previous mail - this
  is not how it's supposed to be.
  I'm currently on it. More news later.
   
I am not sure about that: Linux regular pipes follow the same
behaviour (the real destruction of the file descriptor is delayed
until read() really returns).
  
   My assertion was only based on the idea that nucleus::xnpipe_release()
   must be
  
   called as a result of any close() from the user space.

 If we have a look at the sources, sys_read uses fput_light and
 fget_light, which increment and decrement the file descriptor
 reference count (member f_count of the file structure) used by fget and
 fput when the file descriptor is shared between. open and close call
 fget and fput.

 release only get called through __fput when f_count reaches 0.

Exactly, I have just found out that and posted actually a long mail just 
before getting this mail from you :o)

Yep, and before getting blocked, read() increments the counter as well, that's 
why we don't have a xnpipe_realease() called as a result of close().
So everything is correct.


---

Dmitry