2003-03-20 14:05:43

by Filipau, Ihar

[permalink] [raw]
Subject: read() & close()

Hello All!

[ CC me please - I'm not subscribed ]

I have a question which goes to 2.2 kernels times.
But I expect newer kernels do the same.

I have/had a simple issue with multi-threaded programs:

one thread is doing blocking read(fd) or poll({fd}) on
file/socket.

another thread is doing close(fd).

I expected first thread will unblock with some kind
of error - but nope! It is blocked!

Is it expected behaviour?

I was implementing couple of char device
drivers and I was putting wake_up_interruptible()
into close(). Nice feature - but not more.

Does it really matters?
What standards do say about this? - I have none of
them :-(

P. S. Subject looks correct from point of view of bash:
"read() &" and then "close()" does nothing - %1 can only
be killed ;)

--- Regards&Wishes! With respect
--- Ihar "Philips" Filipau and Phil for friends

- - - - - - - - - - - - - - - - - - - - - - - - -
MCS/Mathematician - System Programmer
Ihar Filipau
Software entwickler @ SUSS MicroTec Test Systems GmbH,
Suss-Strasse 1, D-01561 Sacka (bei Dresden)
e-mail: [email protected] tel: +49-(0)-352-4073-327
fax: +49-(0)-352-4073-700 web: http://www.suss.com/


2003-03-20 14:57:21

by bert hubert

[permalink] [raw]
Subject: Re: read() & close()

On Thu, Mar 20, 2003 at 03:14:52PM +0100, Filipau, Ihar wrote:

> I have/had a simple issue with multi-threaded programs:
>
> one thread is doing blocking read(fd) or poll({fd}) on
> file/socket.

You can't do poll on a file, it won't tell you anything useful, so I assume
you mean a socket.

> another thread is doing close(fd).
>
> I expected first thread will unblock with some kind
> of error - but nope! It is blocked!

Can you show code with this problem?

Regards,

bert

--
http://www.PowerDNS.com Open source, database driven DNS Software
http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
http://netherlabs.nl Consulting

2003-03-20 15:58:27

by Kevin Curtis

[permalink] [raw]
Subject: RE: read() & close()

Hi,
I have come across this problem when implementing a sockets
interface to our X.25 card. On the thread that wants to close the socket,
it must first issue a shutdown(). This will unblock the read() or poll().
And then you can do the close().


Kevin

-----Original Message-----
From: bert hubert [mailto:[email protected]]
Sent: 20 March 2003 15:08
To: Filipau, Ihar
Cc: '[email protected]'
Subject: Re: read() & close()


On Thu, Mar 20, 2003 at 03:14:52PM +0100, Filipau, Ihar wrote:

> I have/had a simple issue with multi-threaded programs:
>
> one thread is doing blocking read(fd) or poll({fd}) on
> file/socket.

You can't do poll on a file, it won't tell you anything useful, so I assume
you mean a socket.

> another thread is doing close(fd).
>
> I expected first thread will unblock with some kind
> of error - but nope! It is blocked!

Can you show code with this problem?

Regards,

bert

--
http://www.PowerDNS.com Open source, database driven DNS Software
http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
http://netherlabs.nl Consulting

2003-03-21 07:58:25

by Filipau, Ihar

[permalink] [raw]
Subject: RE: read() & close()


Thanks for replies.

Mea culpa. Partially ;-)

1. first problem - sockets. I will check shutdown() - but
I am doing shutdown(). This is listen() socket.
Or I was caught with SO_LINGER again... I will check
this again.

2. buggy driver from second party company has no wake_up
in release code. In turn I have copied part of /generic/
code from this driver - so I had same troubles.
I have just checked the (reference for me) pipe/fifo
implementations - they do wake_up in release.

Thanks for the help.

P.S. Actually I have managed to press my management and they
agreed on shift to single-threaded design. So I hope this
will be not a problem any more at all.


>
>
> Hi,
> I have come across this problem when implementing a
> sockets interface to our X.25 card. On the thread that wants
> to close the socket, it must first issue a shutdown(). This
> will unblock the read() or poll(). And then you can do the close().
>
>
> Kevin
>
> -----Original Message-----
> From: bert hubert [mailto:[email protected]]
> Sent: 20 March 2003 15:08
> To: Filipau, Ihar
> Cc: '[email protected]'
> Subject: Re: read() & close()
>
>
> On Thu, Mar 20, 2003 at 03:14:52PM +0100, Filipau, Ihar wrote:
>
> > I have/had a simple issue with multi-threaded programs:
> >
> > one thread is doing blocking read(fd) or poll({fd}) on
> > file/socket.
>
> You can't do poll on a file, it won't tell you anything
> useful, so I assume you mean a socket.
>
> > another thread is doing close(fd).
> >
> > I expected first thread will unblock with some kind
> > of error - but nope! It is blocked!
>
> Can you show code with this problem?
>
> Regards,
>
> bert
>
> --
> http://www.PowerDNS.com Open source, database driven DNS
> Software
> http://lartc.org Linux Advanced Routing & Traffic
> Control HOWTO
> http://netherlabs.nl Consulting
> -
> To unsubscribe from this list: send the line "unsubscribe
> linux-kernel" in the body of a message to
> [email protected] More majordomo info at
http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

2003-03-21 12:24:52

by David Schwartz

[permalink] [raw]
Subject: Re: read() & close()

On Thu, 20 Mar 2003 15:14:52 +0100, Filipau, Ihar wrote:

>I have/had a simple issue with multi-threaded programs:
>
>one thread is doing blocking read(fd) or poll({fd}) on
>file/socket.
>
>another thread is doing close(fd).
>
>I expected first thread will unblock with some kind
>of error - but nope! It is blocked!
>
>Is it expected behaviour?

It is impossible to make this work reliably, so *please* don't do
that. For example, how can you possibly assure that the first thread
is actually in 'poll' when call 'close'? There is no atomic 'release
mutex and poll' function.

So what happens if the system pre-empts the thread right before it
calls 'poll'. Then you call 'close'. Perhaps next a thread started by
some library function calls 'socket' and gets the file descriptor you
just 'close'd. Now your call to 'poll' polls on the *wrong* socket!

You simply must accept the fact that you cannot free a resource in
one thread while another thread is or might be using it.

DS


2003-03-21 12:58:21

by Filipau, Ihar

[permalink] [raw]
Subject: RE: read() & close()



> From: David Schwartz Sent: Freitag, 21. Marz 2003 13:36
> On Thu, 20 Mar 2003 15:14:52 +0100, Filipau, Ihar wrote:
>
> >I have/had a simple issue with multi-threaded programs:
> >
> >one thread is doing blocking read(fd) or poll({fd}) on file/socket.
> >
> >another thread is doing close(fd).
> >
> >I expected first thread will unblock with some kind
> >of error - but nope! It is blocked!
> >
> >Is it expected behaviour?
>
> It is impossible to make this work reliably, so
> *please* don't do
> that. For example, how can you possibly assure that the first thread
> is actually in 'poll' when call 'close'? There is no atomic 'release
> mutex and poll' function.
>
> So what happens if the system pre-empts the thread
> right before it
> calls 'poll'. Then you call 'close'. Perhaps next a thread started by
> some library function calls 'socket' and gets the file descriptor you
> just 'close'd. Now your call to 'poll' polls on the *wrong* socket!
>
> You simply must accept the fact that you cannot free a
> resource in one thread while another thread is or might be using it.
>

In my case I was actually trying to use pipe/socket handle
as a synchronisation point. to signal threads to wake-up at
programme shut-down.

But yes - you are right. This approach is prone to errors.

It looks like in this kind of situations /dev/epoll should be used -
when set of fds is defined before. and all operations on this set
can be easily synchronized.
Sure if /dev/epoll can handle closing of fd correctly - and will
remove it from set.