* 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