public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Eric Dumazet <dada1@cosmosbay.com>
To: Andre Ben Hamou <andre@bluetheta.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Multithread select() bug
Date: Mon, 10 May 2004 23:57:49 +0200	[thread overview]
Message-ID: <409FFADD.7050204@cosmosbay.com> (raw)
In-Reply-To: <409FF38C.7080902@bluetheta.com>

Andre Ben Hamou wrote:

> Here's the scenario...
>
> - parent thread P creates a connected socket pair S[0, 1]
> - P spawns a child thread C and passes it S
> - C selects on S[0]
> - P closes S[0]
>
Your program is racy and have undefined behavior.

A thread should not close a handle 'used by another thread blocked in a 
sytemcall'

The race is : if a thread does a close(fd), then the fd value may be 
reused by another thread during an open()/socket()/dup()... syscall, and 
the first thread could issue the select() syscall (or 
read()/write()/...) on the bad file.

Some Unixes defines different semantics (Solaris comes to mind), but 
these semantics are not part of  standards.

Eric

> As I understand the semantics of the select call, C should now return 
> immediately in response to the closure (and it does on Mac OS X). 
> However, the following test code behaves otherwise for the two test 
> cases I've tried (2.4.21 and 2.6.5). Compilation command used: 'gcc 
> foobar.c -lpthread'.
>
> Cheers,
>
> Andre Ben Hamou
> Imperial College London
>
>
> --- BEGIN TEST CODE (foobar.c)---
>
> #include <assert.h>         // assert
> #include <pthread.h>        // pthread_create
> #include <sys/select.h>     // select
> #include <sys/types.h>      // socketpair
> #include <sys/socket.h>     // socketpair
> #include <unistd.h>         // sleep
> #include <stdio.h>          // printf
>
> void *threadFuntion (void *sockets) {
>     int socket = ((int *)sockets)[0];
>     struct timeval timeout = {tv_sec: 5, tv_usec: 0};
>
>     // Allocate a file descriptor set with the passed socket
>     fd_set fds;
>     FD_ZERO (&fds);
>     FD_SET (socket, &fds);
>
>     // Select to read / register exceptions on the FD set
>     select (socket + 1, &fds, NULL, &fds, &timeout);
>
>     return NULL;
> }
>
> int main (void) {
>     int sockets[2];
>     pthread_t thread;
>
>     // Create a connected pair of sockets
>     assert (socketpair (PF_UNIX, SOCK_STREAM, 0, sockets) != -1);
>     printf ("sockets: {%i, %i}\n", sockets[0], sockets[1]);
>
>     // Create a POSIX thread
>     // - use the default configuration
>     // - invoke 'threadFunction' as the root function of the thread
>     // - pass the socket array to 'threadFunction'
>     assert (pthread_create (&thread,
>                 NULL,
>                             threadFuntion,
>                             sockets) == 0);
>
>     // Wait for a second and then close the socket being selected on
>     sleep (1);
>     assert (close (sockets[0]) == 0);
>     printf ("Socket closed\n");
>
>     // Wait for the thread to exit - SHOULD BE ~ INSTANTANEOUS
>     assert (pthread_join (thread, NULL) == 0);
>     printf ("Thread joined\n");
>
>     assert (close (sockets[1]) == 0);
>     return 0;
> }
>
> --- END TEST CODE ---
>


  parent reply	other threads:[~2004-05-10 21:59 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-10 21:26 Multithread select() bug Andre Ben Hamou
2004-05-10 21:47 ` Davide Libenzi
2004-05-10 21:56   ` Andre Ben Hamou
2004-05-10 22:09     ` Davide Libenzi
2004-05-10 21:57 ` Eric Dumazet [this message]
2004-05-10 22:11   ` Andre Ben Hamou
2004-05-10 22:31     ` Eric Dumazet
2004-05-10 23:01       ` Andre Ben Hamou
2004-05-11  6:07         ` Armin Schindler
2004-05-11  6:24         ` Eric Dumazet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=409FFADD.7050204@cosmosbay.com \
    --to=dada1@cosmosbay.com \
    --cc=andre@bluetheta.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox