From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Simon Wright Newsgroups: comp.lang.ada Subject: Re: GNAT implementation of socket sets Date: Fri, 19 Jan 2018 19:10:36 +0000 Organization: A noiseless patient Spider Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="2b89bd3d01304853b38669b28ca5b559"; logging-data="31441"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18OWBlR85Je3uKq5v3TVcwUHsfIfkRuUlU=" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (darwin) Cancel-Lock: sha1:ThE8V36pEeblwMr+yChQSqIWwEQ= sha1:0asRUtz55gsMIV5vYQutvwKK+Dg= Xref: reader02.eternal-september.org comp.lang.ada:50011 Date: 2018-01-19T19:10:36+00:00 List-Id: "Dmitry A. Kazakov" 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; }