comp.lang.ada
 help / color / mirror / Atom feed
* GNAT implementation of socket sets
@ 2018-01-19 17:29 Dmitry A. Kazakov
  2018-01-19 19:10 ` Simon Wright
  0 siblings, 1 reply; 2+ messages in thread
From: Dmitry A. Kazakov @ 2018-01-19 17:29 UTC (permalink / raw)


GNAT.Sockets implementation of Socket_Set_Type has no operation to walk 
that set by position. It seemed not a big issue until I noticed that the 
implementation of

    procedure Get (Item : in out Socket_Set_Type; Socket : out Socket_Type);
    --  Extract a Socket from socket set Item. Socket is set to
    --  No_Socket when the set is empty.

seems to always return the last element of the set.

If so, it imposes a severe problem for an application that deals with 
multiple non-blocking sockets, because it prioritizes connections with 
sockets with greater file numbers. Under heavy load the application will 
serve only one connection.

Typically such issues are resolved by a round-robin schema to balance 
the load. But that requires walking the set and extracting an element at 
a position.

Can anybody confirm that and suggest a workaround?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: GNAT implementation of socket sets
  2018-01-19 17:29 GNAT implementation of socket sets Dmitry A. Kazakov
@ 2018-01-19 19:10 ` Simon Wright
  0 siblings, 0 replies; 2+ messages in thread
From: Simon Wright @ 2018-01-19 19:10 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> GNAT.Sockets implementation of Socket_Set_Type has no operation to
> walk that set by position. It seemed not a big issue until I noticed
> that the implementation of
>
>    procedure Get (Item : in out Socket_Set_Type; Socket : out Socket_Type);
>    --  Extract a Socket from socket set Item. Socket is set to
>    --  No_Socket when the set is empty.
>
> seems to always return the last element of the set.

Indeed.

Implemented as:

   /* Get last socket and remove it from the socket set SET.  LAST is the
      maximum value of the largest socket.  This hint is used to avoid scanning
      very large socket sets.  On return, LAST is set to the actual largest
      socket in the socket set. */

   void
   __gnat_get_socket_from_set (fd_set *set, int *last, int *socket)
   {
     *socket = *last;
     FD_CLR (*socket, set);
     __gnat_last_socket_in_set (set, last);
   }

where

   void
   __gnat_last_socket_in_set (fd_set *set, int *last)
   {
     int s;
     int l;
     l = -1;

   #ifdef _WIN32
     /* More efficient method for NT. */
     for (s = 0; s < set->fd_count; s++)
       if ((int) set->fd_array[s] > l)
         l = set->fd_array[s];

   #else

     for (s = *last; s != -1; s--)
       if (FD_ISSET (s, set))
         {
           l = s;
           break;
         }
   #endif

     *last = l;
   }


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-01-19 19:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-19 17:29 GNAT implementation of socket sets Dmitry A. Kazakov
2018-01-19 19:10 ` Simon Wright

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox