| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | /* | 
| 2 |  |  |  |  |  |  | * libev select fd activity backend | 
| 3 |  |  |  |  |  |  | * | 
| 4 |  |  |  |  |  |  | * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann | 
| 5 |  |  |  |  |  |  | * All rights reserved. | 
| 6 |  |  |  |  |  |  | * | 
| 7 |  |  |  |  |  |  | * Redistribution and use in source and binary forms, with or without modifica- | 
| 8 |  |  |  |  |  |  | * tion, are permitted provided that the following conditions are met: | 
| 9 |  |  |  |  |  |  | * | 
| 10 |  |  |  |  |  |  | *   1.  Redistributions of source code must retain the above copyright notice, | 
| 11 |  |  |  |  |  |  | *       this list of conditions and the following disclaimer. | 
| 12 |  |  |  |  |  |  | * | 
| 13 |  |  |  |  |  |  | *   2.  Redistributions in binary form must reproduce the above copyright | 
| 14 |  |  |  |  |  |  | *       notice, this list of conditions and the following disclaimer in the | 
| 15 |  |  |  |  |  |  | *       documentation and/or other materials provided with the distribution. | 
| 16 |  |  |  |  |  |  | * | 
| 17 |  |  |  |  |  |  | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | 
| 18 |  |  |  |  |  |  | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- | 
| 19 |  |  |  |  |  |  | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO | 
| 20 |  |  |  |  |  |  | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- | 
| 21 |  |  |  |  |  |  | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
| 22 |  |  |  |  |  |  | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 
| 23 |  |  |  |  |  |  | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | 
| 24 |  |  |  |  |  |  | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- | 
| 25 |  |  |  |  |  |  | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 
| 26 |  |  |  |  |  |  | * OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 27 |  |  |  |  |  |  | * | 
| 28 |  |  |  |  |  |  | * Alternatively, the contents of this file may be used under the terms of | 
| 29 |  |  |  |  |  |  | * the GNU General Public License ("GPL") version 2 or any later version, | 
| 30 |  |  |  |  |  |  | * in which case the provisions of the GPL are applicable instead of | 
| 31 |  |  |  |  |  |  | * the above. If you wish to allow the use of your version of this file | 
| 32 |  |  |  |  |  |  | * only under the terms of the GPL and not to allow others to use your | 
| 33 |  |  |  |  |  |  | * version of this file under the BSD license, indicate your decision | 
| 34 |  |  |  |  |  |  | * by deleting the provisions above and replace them with the notice | 
| 35 |  |  |  |  |  |  | * and other provisions required by the GPL. If you do not delete the | 
| 36 |  |  |  |  |  |  | * provisions above, a recipient may use your version of this file under | 
| 37 |  |  |  |  |  |  | * either the BSD or the GPL. | 
| 38 |  |  |  |  |  |  | */ | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | #ifndef _WIN32 | 
| 41 |  |  |  |  |  |  | /* for unix systems */ | 
| 42 |  |  |  |  |  |  | # include | 
| 43 |  |  |  |  |  |  | # ifndef __hpux | 
| 44 |  |  |  |  |  |  | /* for REAL unix systems */ | 
| 45 |  |  |  |  |  |  | #  include | 
| 46 |  |  |  |  |  |  | # endif | 
| 47 |  |  |  |  |  |  | #endif | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | #ifndef EV_SELECT_USE_FD_SET | 
| 50 |  |  |  |  |  |  | # ifdef NFDBITS | 
| 51 |  |  |  |  |  |  | #  define EV_SELECT_USE_FD_SET 0 | 
| 52 |  |  |  |  |  |  | # else | 
| 53 |  |  |  |  |  |  | #  define EV_SELECT_USE_FD_SET 1 | 
| 54 |  |  |  |  |  |  | # endif | 
| 55 |  |  |  |  |  |  | #endif | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | #if EV_SELECT_IS_WINSOCKET | 
| 58 |  |  |  |  |  |  | # undef EV_SELECT_USE_FD_SET | 
| 59 |  |  |  |  |  |  | # define EV_SELECT_USE_FD_SET 1 | 
| 60 |  |  |  |  |  |  | # undef NFDBITS | 
| 61 |  |  |  |  |  |  | # define NFDBITS 0 | 
| 62 |  |  |  |  |  |  | #endif | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | #if !EV_SELECT_USE_FD_SET | 
| 65 |  |  |  |  |  |  | # define NFDBYTES (NFDBITS / 8) | 
| 66 |  |  |  |  |  |  | #endif | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | #include | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | static void | 
| 71 | 0 |  |  |  |  |  | select_modify (EV_P_ int fd, int oev, int nev) | 
| 72 |  |  |  |  |  |  | { | 
| 73 | 0 | 0 |  |  |  |  | if (oev == nev) | 
| 74 | 0 |  |  |  |  |  | return; | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | { | 
| 77 |  |  |  |  |  |  | #if EV_SELECT_USE_FD_SET | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | #if EV_SELECT_IS_WINSOCKET | 
| 80 |  |  |  |  |  |  | SOCKET handle = anfds [fd].handle; | 
| 81 |  |  |  |  |  |  | #else | 
| 82 |  |  |  |  |  |  | int handle = fd; | 
| 83 |  |  |  |  |  |  | #endif | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE)); | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | /* FD_SET is broken on windows (it adds the fd to a set twice or more, | 
| 88 |  |  |  |  |  |  | * which eventually leads to overflows). Need to call it only on changes. | 
| 89 |  |  |  |  |  |  | */ | 
| 90 |  |  |  |  |  |  | #if EV_SELECT_IS_WINSOCKET | 
| 91 |  |  |  |  |  |  | if ((oev ^ nev) & EV_READ) | 
| 92 |  |  |  |  |  |  | #endif | 
| 93 |  |  |  |  |  |  | if (nev & EV_READ) | 
| 94 |  |  |  |  |  |  | FD_SET (handle, (fd_set *)vec_ri); | 
| 95 |  |  |  |  |  |  | else | 
| 96 |  |  |  |  |  |  | FD_CLR (handle, (fd_set *)vec_ri); | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | #if EV_SELECT_IS_WINSOCKET | 
| 99 |  |  |  |  |  |  | if ((oev ^ nev) & EV_WRITE) | 
| 100 |  |  |  |  |  |  | #endif | 
| 101 |  |  |  |  |  |  | if (nev & EV_WRITE) | 
| 102 |  |  |  |  |  |  | FD_SET (handle, (fd_set *)vec_wi); | 
| 103 |  |  |  |  |  |  | else | 
| 104 |  |  |  |  |  |  | FD_CLR (handle, (fd_set *)vec_wi); | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | #else | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 0 |  |  |  |  |  | int     word = fd / NFDBITS; | 
| 109 | 0 |  |  |  |  |  | fd_mask mask = 1UL << (fd % NFDBITS); | 
| 110 |  |  |  |  |  |  |  | 
| 111 | 0 | 0 |  |  |  |  | if (ecb_expect_false (vec_max <= word)) | 
| 112 |  |  |  |  |  |  | { | 
| 113 | 0 |  |  |  |  |  | int new_max = word + 1; | 
| 114 |  |  |  |  |  |  |  | 
| 115 | 0 |  |  |  |  |  | vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES); | 
| 116 | 0 |  |  |  |  |  | vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */ | 
| 117 | 0 |  |  |  |  |  | vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES); | 
| 118 | 0 |  |  |  |  |  | vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */ | 
| 119 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 120 |  |  |  |  |  |  | vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */ | 
| 121 |  |  |  |  |  |  | #endif | 
| 122 |  |  |  |  |  |  |  | 
| 123 | 0 | 0 |  |  |  |  | for (; vec_max < new_max; ++vec_max) | 
| 124 | 0 |  |  |  |  |  | ((fd_mask *)vec_ri) [vec_max] = | 
| 125 | 0 |  |  |  |  |  | ((fd_mask *)vec_wi) [vec_max] = 0; | 
| 126 |  |  |  |  |  |  | } | 
| 127 |  |  |  |  |  |  |  | 
| 128 | 0 |  |  |  |  |  | ((fd_mask *)vec_ri) [word] |= mask; | 
| 129 | 0 | 0 |  |  |  |  | if (!(nev & EV_READ)) | 
| 130 | 0 |  |  |  |  |  | ((fd_mask *)vec_ri) [word] &= ~mask; | 
| 131 |  |  |  |  |  |  |  | 
| 132 | 0 |  |  |  |  |  | ((fd_mask *)vec_wi) [word] |= mask; | 
| 133 | 0 | 0 |  |  |  |  | if (!(nev & EV_WRITE)) | 
| 134 | 0 |  |  |  |  |  | ((fd_mask *)vec_wi) [word] &= ~mask; | 
| 135 |  |  |  |  |  |  | #endif | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  | } | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | static void | 
| 140 | 0 |  |  |  |  |  | select_poll (EV_P_ ev_tstamp timeout) | 
| 141 |  |  |  |  |  |  | { | 
| 142 |  |  |  |  |  |  | struct timeval tv; | 
| 143 |  |  |  |  |  |  | int res; | 
| 144 |  |  |  |  |  |  | int fd_setsize; | 
| 145 |  |  |  |  |  |  |  | 
| 146 | 0 | 0 |  |  |  |  | EV_RELEASE_CB; | 
| 147 | 0 |  |  |  |  |  | EV_TV_SET (tv, timeout); | 
| 148 |  |  |  |  |  |  |  | 
| 149 |  |  |  |  |  |  | #if EV_SELECT_USE_FD_SET | 
| 150 |  |  |  |  |  |  | fd_setsize = sizeof (fd_set); | 
| 151 |  |  |  |  |  |  | #else | 
| 152 | 0 |  |  |  |  |  | fd_setsize = vec_max * NFDBYTES; | 
| 153 |  |  |  |  |  |  | #endif | 
| 154 |  |  |  |  |  |  |  | 
| 155 | 0 |  |  |  |  |  | memcpy (vec_ro, vec_ri, fd_setsize); | 
| 156 | 0 |  |  |  |  |  | memcpy (vec_wo, vec_wi, fd_setsize); | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 159 |  |  |  |  |  |  | /* pass in the write set as except set. | 
| 160 |  |  |  |  |  |  | * the idea behind this is to work around a windows bug that causes | 
| 161 |  |  |  |  |  |  | * errors to be reported as an exception and not by setting | 
| 162 |  |  |  |  |  |  | * the writable bit. this is so uncontrollably lame. | 
| 163 |  |  |  |  |  |  | */ | 
| 164 |  |  |  |  |  |  | memcpy (vec_eo, vec_wi, fd_setsize); | 
| 165 |  |  |  |  |  |  | res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv); | 
| 166 |  |  |  |  |  |  | #elif EV_SELECT_USE_FD_SET | 
| 167 |  |  |  |  |  |  | fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE; | 
| 168 |  |  |  |  |  |  | res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); | 
| 169 |  |  |  |  |  |  | #else | 
| 170 | 0 |  |  |  |  |  | res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); | 
| 171 |  |  |  |  |  |  | #endif | 
| 172 | 0 | 0 |  |  |  |  | EV_ACQUIRE_CB; | 
| 173 |  |  |  |  |  |  |  | 
| 174 | 0 | 0 |  |  |  |  | if (ecb_expect_false (res < 0)) | 
| 175 |  |  |  |  |  |  | { | 
| 176 |  |  |  |  |  |  | #if EV_SELECT_IS_WINSOCKET | 
| 177 |  |  |  |  |  |  | errno = WSAGetLastError (); | 
| 178 |  |  |  |  |  |  | #endif | 
| 179 |  |  |  |  |  |  | #ifdef WSABASEERR | 
| 180 |  |  |  |  |  |  | /* on windows, select returns incompatible error codes, fix this */ | 
| 181 |  |  |  |  |  |  | if (errno >= WSABASEERR && errno < WSABASEERR + 1000) | 
| 182 |  |  |  |  |  |  | if (errno == WSAENOTSOCK) | 
| 183 |  |  |  |  |  |  | errno = EBADF; | 
| 184 |  |  |  |  |  |  | else | 
| 185 |  |  |  |  |  |  | errno -= WSABASEERR; | 
| 186 |  |  |  |  |  |  | #endif | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 189 |  |  |  |  |  |  | /* select on windows erroneously returns EINVAL when no fd sets have been | 
| 190 |  |  |  |  |  |  | * provided (this is documented). what microsoft doesn't tell you that this bug | 
| 191 |  |  |  |  |  |  | * exists even when the fd sets _are_ provided, so we have to check for this bug | 
| 192 |  |  |  |  |  |  | * here and emulate by sleeping manually. | 
| 193 |  |  |  |  |  |  | * we also get EINVAL when the timeout is invalid, but we ignore this case here | 
| 194 |  |  |  |  |  |  | * and assume that EINVAL always means: you have to wait manually. | 
| 195 |  |  |  |  |  |  | */ | 
| 196 |  |  |  |  |  |  | if (errno == EINVAL) | 
| 197 |  |  |  |  |  |  | { | 
| 198 |  |  |  |  |  |  | if (timeout) | 
| 199 |  |  |  |  |  |  | { | 
| 200 |  |  |  |  |  |  | unsigned long ms = EV_TS_TO_MSEC (timeout); | 
| 201 |  |  |  |  |  |  | Sleep (ms ? ms : 1); | 
| 202 |  |  |  |  |  |  | } | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | return; | 
| 205 |  |  |  |  |  |  | } | 
| 206 |  |  |  |  |  |  | #endif | 
| 207 |  |  |  |  |  |  |  | 
| 208 | 0 | 0 |  |  |  |  | if (errno == EBADF) | 
| 209 | 0 |  |  |  |  |  | fd_ebadf (EV_A); | 
| 210 | 0 | 0 |  |  |  |  | else if (errno == ENOMEM && !syserr_cb) | 
|  |  | 0 |  |  |  |  |  | 
| 211 | 0 |  |  |  |  |  | fd_enomem (EV_A); | 
| 212 | 0 | 0 |  |  |  |  | else if (errno != EINTR) | 
| 213 | 0 |  |  |  |  |  | ev_syserr ("(libev) select"); | 
| 214 |  |  |  |  |  |  |  | 
| 215 | 0 |  |  |  |  |  | return; | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | #if EV_SELECT_USE_FD_SET | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | { | 
| 221 |  |  |  |  |  |  | int fd; | 
| 222 |  |  |  |  |  |  |  | 
| 223 |  |  |  |  |  |  | for (fd = 0; fd < anfdmax; ++fd) | 
| 224 |  |  |  |  |  |  | if (anfds [fd].events) | 
| 225 |  |  |  |  |  |  | { | 
| 226 |  |  |  |  |  |  | int events = 0; | 
| 227 |  |  |  |  |  |  | #if EV_SELECT_IS_WINSOCKET | 
| 228 |  |  |  |  |  |  | SOCKET handle = anfds [fd].handle; | 
| 229 |  |  |  |  |  |  | #else | 
| 230 |  |  |  |  |  |  | int handle = fd; | 
| 231 |  |  |  |  |  |  | #endif | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ; | 
| 234 |  |  |  |  |  |  | if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE; | 
| 235 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 236 |  |  |  |  |  |  | if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE; | 
| 237 |  |  |  |  |  |  | #endif | 
| 238 |  |  |  |  |  |  |  | 
| 239 |  |  |  |  |  |  | if (ecb_expect_true (events)) | 
| 240 |  |  |  |  |  |  | fd_event (EV_A_ fd, events); | 
| 241 |  |  |  |  |  |  | } | 
| 242 |  |  |  |  |  |  | } | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | #else | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | { | 
| 247 |  |  |  |  |  |  | int word, bit; | 
| 248 | 0 | 0 |  |  |  |  | for (word = vec_max; word--; ) | 
| 249 |  |  |  |  |  |  | { | 
| 250 | 0 |  |  |  |  |  | fd_mask word_r = ((fd_mask *)vec_ro) [word]; | 
| 251 | 0 |  |  |  |  |  | fd_mask word_w = ((fd_mask *)vec_wo) [word]; | 
| 252 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 253 |  |  |  |  |  |  | word_w |= ((fd_mask *)vec_eo) [word]; | 
| 254 |  |  |  |  |  |  | #endif | 
| 255 |  |  |  |  |  |  |  | 
| 256 | 0 | 0 |  |  |  |  | if (word_r || word_w) | 
|  |  | 0 |  |  |  |  |  | 
| 257 | 0 | 0 |  |  |  |  | for (bit = NFDBITS; bit--; ) | 
| 258 |  |  |  |  |  |  | { | 
| 259 | 0 |  |  |  |  |  | fd_mask mask = 1UL << bit; | 
| 260 | 0 |  |  |  |  |  | int events = 0; | 
| 261 |  |  |  |  |  |  |  | 
| 262 | 0 |  |  |  |  |  | events |= word_r & mask ? EV_READ  : 0; | 
| 263 | 0 | 0 |  |  |  |  | events |= word_w & mask ? EV_WRITE : 0; | 
| 264 |  |  |  |  |  |  |  | 
| 265 | 0 | 0 |  |  |  |  | if (ecb_expect_true (events)) | 
| 266 | 0 |  |  |  |  |  | fd_event (EV_A_ word * NFDBITS + bit, events); | 
| 267 |  |  |  |  |  |  | } | 
| 268 |  |  |  |  |  |  | } | 
| 269 |  |  |  |  |  |  | } | 
| 270 |  |  |  |  |  |  |  | 
| 271 |  |  |  |  |  |  | #endif | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | inline_size | 
| 275 |  |  |  |  |  |  | int | 
| 276 | 0 |  |  |  |  |  | select_init (EV_P_ int flags) | 
| 277 |  |  |  |  |  |  | { | 
| 278 | 0 |  |  |  |  |  | backend_mintime = EV_TS_CONST (1e-6); | 
| 279 | 0 |  |  |  |  |  | backend_modify  = select_modify; | 
| 280 | 0 |  |  |  |  |  | backend_poll    = select_poll; | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | #if EV_SELECT_USE_FD_SET | 
| 283 |  |  |  |  |  |  | vec_ri  = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri); | 
| 284 |  |  |  |  |  |  | vec_ro  = ev_malloc (sizeof (fd_set)); | 
| 285 |  |  |  |  |  |  | vec_wi  = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi); | 
| 286 |  |  |  |  |  |  | vec_wo  = ev_malloc (sizeof (fd_set)); | 
| 287 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 288 |  |  |  |  |  |  | vec_eo  = ev_malloc (sizeof (fd_set)); | 
| 289 |  |  |  |  |  |  | #endif | 
| 290 |  |  |  |  |  |  | #else | 
| 291 | 0 |  |  |  |  |  | vec_max = 0; | 
| 292 | 0 |  |  |  |  |  | vec_ri  = 0; | 
| 293 | 0 |  |  |  |  |  | vec_ro  = 0; | 
| 294 | 0 |  |  |  |  |  | vec_wi  = 0; | 
| 295 | 0 |  |  |  |  |  | vec_wo  = 0; | 
| 296 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 297 |  |  |  |  |  |  | vec_eo  = 0; | 
| 298 |  |  |  |  |  |  | #endif | 
| 299 |  |  |  |  |  |  | #endif | 
| 300 |  |  |  |  |  |  |  | 
| 301 | 0 |  |  |  |  |  | return EVBACKEND_SELECT; | 
| 302 |  |  |  |  |  |  | } | 
| 303 |  |  |  |  |  |  |  | 
| 304 |  |  |  |  |  |  | inline_size | 
| 305 |  |  |  |  |  |  | void | 
| 306 | 0 |  |  |  |  |  | select_destroy (EV_P) | 
| 307 |  |  |  |  |  |  | { | 
| 308 | 0 |  |  |  |  |  | ev_free (vec_ri); | 
| 309 | 0 |  |  |  |  |  | ev_free (vec_ro); | 
| 310 | 0 |  |  |  |  |  | ev_free (vec_wi); | 
| 311 | 0 |  |  |  |  |  | ev_free (vec_wo); | 
| 312 |  |  |  |  |  |  | #ifdef _WIN32 | 
| 313 |  |  |  |  |  |  | ev_free (vec_eo); | 
| 314 |  |  |  |  |  |  | #endif | 
| 315 | 0 |  |  |  |  |  | } | 
| 316 |  |  |  |  |  |  |  |