2004-03-02 12:31:29

by Ben

[permalink] [raw]
Subject: epoll and fork()

Is there a defined behaviour for what happens when a process with an epoll
fd forks?

I've an app that inherits an epoll fd from its parent, and then
unregisters some file descriptors from the epoll set. This seems to have
the nasty side effect of unregistering the same file descriptors from the
parent process as well. Surely this can't be right?

This is on 2.6.2.


Ben


2004-03-02 12:58:44

by Mihai Rusu

[permalink] [raw]
Subject: Re: epoll and fork()

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 2 Mar 2004, Ben wrote:

> Is there a defined behaviour for what happens when a process with an epoll
> fd forks?
>
> I've an app that inherits an epoll fd from its parent, and then
> unregisters some file descriptors from the epoll set. This seems to have
> the nasty side effect of unregistering the same file descriptors from the
> parent process as well. Surely this can't be right?
>
> This is on 2.6.2.

Currect me if Im wrong but...

After a fork() arent all the parent's fds shared with the children ? This
means that both processes can access the same fds right ? So the epoll fd
(beeing just another fd as any other) is too shared between parent and
child ? Which would mean both parent and child will "control" the same
epoll kernel struct when doing epoll_ctl on it ?

> Ben

- --
Mihai RUSU Email: [email protected]
GPG : http://dizzy.roedu.net/dizzy-gpg.txt WWW: http://dizzy.roedu.net
"Linux is obsolete" -- AST
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFARIVAPZzOzrZY/1QRAs+vAKCrkH/jSsJRCU6leScXz4EXC4kruQCeJfFo
/remKED2xAru7uInLoyhl4o=
=2cDV
-----END PGP SIGNATURE-----

2004-03-02 13:19:12

by Richard B. Johnson

[permalink] [raw]
Subject: Re: epoll and fork()

On Tue, 2 Mar 2004, Mihai RUSU wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Tue, 2 Mar 2004, Ben wrote:
>
> > Is there a defined behaviour for what happens when a process with an epoll
> > fd forks?
> >
> > I've an app that inherits an epoll fd from its parent, and then
> > unregisters some file descriptors from the epoll set. This seems to have
> > the nasty side effect of unregistering the same file descriptors from the
> > parent process as well. Surely this can't be right?
> >
> > This is on 2.6.2.
>
> Currect me if Im wrong but...
>
> After a fork() arent all the parent's fds shared with the children ? This
> means that both processes can access the same fds right ? So the epoll fd
> (beeing just another fd as any other) is too shared between parent and
> child ? Which would mean both parent and child will "control" the same
> epoll kernel struct when doing epoll_ctl on it ?
>
> > Ben
>

The child's fds are separate, though. The parent can close
its fds without affecting the child's and the child can close
its fds without affecting the parent. Given that, suppose that
the fds related to a terminal. If the child changed the terminal
attributes, this would certainly affect the parent's terminal
since they are the same. It is possible that epoll handles
these attributes the same way and it is likely that such
behavior is "undefined". A fix may be for the child to dup()
the fds and set up its own epoll_ctl using them. If the epoll
relates to a controlling terminal, it is possible that if the
child executes setsid(), becomes its own session leader, then
the epoll problem will go away because the parent's controlling
terminal and the child's controlling terminal become divorced.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.24 on an i686 machine (797.90 BogoMips).
Note 96.31% of all statistics are fiction.


2004-03-02 14:01:24

by Mihai Rusu

[permalink] [raw]
Subject: Re: epoll and fork()

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 2 Mar 2004, Richard B. Johnson wrote:

> The child's fds are separate, though. The parent can close
> its fds without affecting the child's and the child can close
> its fds without affecting the parent.

They are not separate. It just that when using close you decrement the
"reference" count to the "real" fd struct (like done on FS inodes). When
reaches 0 its closed. So still as I said, fds are shared ;)

I havent check kernel sources, I just say that the fact the you can and
need to close() a shared fd on each sharing process doesnt mean the
sockets are independent.

- --
Mihai RUSU Email: [email protected]
GPG : http://dizzy.roedu.net/dizzy-gpg.txt WWW: http://dizzy.roedu.net
"Linux is obsolete" -- AST
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFARJPwPZzOzrZY/1QRAulNAKDAHLz2mVPIfADedlIWA2U3QQFuFQCdFQyo
V5hpmpt+1r4DQDP1PTQig/k=
=HtbW
-----END PGP SIGNATURE-----

2004-03-02 15:44:02

by Mark Mielke

[permalink] [raw]
Subject: Re: epoll and fork()

On Tue, Mar 02, 2004 at 12:31:20PM +0000, Ben wrote:
> Is there a defined behaviour for what happens when a process with an epoll
> fd forks?

You found it. :-)

> I've an app that inherits an epoll fd from its parent, and then
> unregisters some file descriptors from the epoll set. This seems to have
> the nasty side effect of unregistering the same file descriptors from the
> parent process as well. Surely this can't be right?

The epoll fd should probably be closed after the fork(), re-allocated,
and then initialized to contain the file descriptors that you want to
watch.

mark

--
[email protected]/[email protected]/[email protected] __________________________
. . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder
|\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ |
| | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada

One ring to rule them all, one ring to find them, one ring to bring them all
and in the darkness bind them...

http://mark.mielke.cc/