Subject: Re: reached select() limit

Re: reached select() limit

From: eugeny gladkih <john_at_drweb.com>
Date: Tue, 31 Jan 2017 16:41:45 +0300

On 01/25/2017 02:18 AM, David Guillen Fandos wrote:
> Hello,
>
> I wrote an app that was crashing in c-ares due to fds being bigger than
> 1024. While c-ares might be using around 30 fds it is unable to use fds
> above 1024.
>

no, that's not a truth. you may use any socket number on all modern UNIX
systems. the only thing you need - you have to allocate enough memory
for fd_set. one more thing you have to know is still here. on Solaris
you may define the FD_SETSIZE preprocessor constant to any numer which
is big enough.

the sample C++ code (1st call prepare()):

   class unx_fd_set_t {
     char *Ptr;
     size_t MFd;
     long Psize;
     size_t Sz;

     void init0( size_t nSz ) {
       char *nPtr = new char[ nSz ];

       if( !nPtr )
         d_exception_raise( "no enough memory" );

       delete[] Ptr;

       Sz = nSz;
       Ptr = nPtr;
     }

     void init() {
       // filled up to 32 bytes + 32 bytes gap
       size_t nSz = (((MFd + 8)/8)/Psize + 1)*Psize;

       if( nSz > Sz )
         init0( nSz );
     }

     void prepare( size_t mFd ) {
       if( mFd > MFd ) {
         MFd = mFd;
         init();
       }

       memset( Ptr, 0, Sz );
     }

   public:
     unx_fd_set_t() : Ptr( 0 ), MFd( 0 ), Psize( sysconf( _SC_PAGESIZE )
), Sz( 0 ) {
       if( Psize <= 0 ) Psize = 4096;

       init();
       memset( Ptr, 0, Sz );
     }

     ~unx_fd_set_t() { delete[] Ptr; }

     void set_fd( int fd ) { FD_SET( fd, (fd_set*)Ptr ); }
     void clr_fd( int fd ) { FD_CLR( fd, (fd_set*)Ptr ); }
     bool is_set( int fd ) { return FD_ISSET( fd, (fd_set*)Ptr ); }

     fd_set *set() { return (fd_set *)Ptr; }
   };

-- 
Yours sincerely, Eugeny.
GM of Enterprise Solutions Department
Doctor Web, Ltd.
http://www.drweb.com, +79119997425
Received on 2017-01-31