[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)



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 mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


[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



[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  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 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).

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 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

___
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-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  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 mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


[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 mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


[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 mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core