Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Oct 2011 18:18:39 +0200
From:      Vikash Badal <Vikash.Badal@is.co.za>
To:        "freebsd-questions@freebsd.org" <freebsd-questions@freebsd.org>
Subject:   probably stupid questions about select() and FS_SET in a multithreaded environment [ select() failed (Bad file descriptor) ]
Message-ID:  <9B425C841283E0418B1825D40CBCFA616E38A1AC3D@ZABRYSVISEXMBX1.af.didata.local>

next in thread | raw e-mail | index | archive | help
Greetings,

Can some point me in the correction direction please.

I have a treaded socket application that has a problem with select() retu=
rning -1.
The select() and accept() is taken care of in one thread. The worker thre=
ads deal with client requests after the new client connection is pushed t=
o queue.

The logged error is :
select() failed (Bad file descriptor) getdtablesize =3D 65536

Sysctls at the moment  are:
kern.maxfiles: 65536=20
kern.maxfilesperproc: 65536


<code>
void client_accept(int listen_socket)
{
...
=20  while ( loop )
=20  {
=20     FD_ZERO(&socket_set);
=20     FD_SET(listen_socket, &socket_set);
=20     timeout.tv_sec =3D 1;
=20     timeout.tv_usec =3D 0;

=20     rcode =3D select(listen_socket + 1, &socket_set, NULL, NULL, &tim=
eout);

=20     if ( rcode < 0 )
=20     {
=20        Log(DEBUG_0, "ERROR: select() failed (%s) getdtablesize =3D %d=
",
=20            strerror(errno), getdtablesize());
=20        loop =3D 0;
=20        sleep(30);
=20        fcloseall();
=20        assert(1=3D=3D0);
=20     }

=20     if ( rcode > 0 )
=20     {
=20         remotelen =3D sizeof(remote);
=20         client_sock =3D accept(listen_socket, .....
=20        =20
=20         if (msgsock !=3D -1 )
=20         {=20
=20            // Allocate memory for request
=20            request =3D malloc(sizeof(struct requests));
=20            // test for malloc etc ...
=20            // set request values ...
=20            //
=20            // Push request to a queue.=20
=20         }
=20     }

=20  }
=20...
}
void* tcpworker(void* arg)
{
=20  // initialise stuff

=20  While ( loop )
=20  {
=20     // pop request from queue
=20    =20
=20     If ( request !=3D NULL )
=20     {
=20        // deal with request
=20        free(request)
=20     }
=20  }  =20
}

</code>
When the problem occurs, i have between 1000 and 1400 clients connected.

Questions:
1. do i need to FD_CLR(client_sock,&socket_set) before i push to a queue =
?
2. do i need to FD_CLR(client_sock, &socket_set) when this client request=
=20closes in the the tcpworker() function ?
3. would setting kern.maxfilesperproc and kern.maxfiles to higher values =
solve the problem or just take longer for the problem to re-appear.
4. should is replace select() with kqueue() as from google-ing it seems s=
elect() is not that great.


Thanks
Vikash

Please note: This email and its content are subject to the disclaimer as =
displayed at the following link http://www.is.co.za/legal/E-mail+Confiden=
tiality+Notice+and+Disclaimer.htm. Should you not have Web access, send a=
=20mail to disclaimers@is.co.za and a copy will be emailed to you.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9B425C841283E0418B1825D40CBCFA616E38A1AC3D>