Lingfeng Yang | a2a3b0f | 2020-11-04 11:50:46 -0800 | [diff] [blame] | 1 | /* |
| 2 | |
| 3 | Copyright 1994, 1998 The Open Group |
| 4 | |
| 5 | Permission to use, copy, modify, distribute, and sell this software and its |
| 6 | documentation for any purpose is hereby granted without fee, provided that |
| 7 | the above copyright notice appear in all copies and that both that |
| 8 | copyright notice and this permission notice appear in supporting |
| 9 | documentation. |
| 10 | |
| 11 | The above copyright notice and this permission notice shall be included |
| 12 | in all copies or substantial portions of the Software. |
| 13 | |
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 17 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| 18 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| 19 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 20 | OTHER DEALINGS IN THE SOFTWARE. |
| 21 | |
| 22 | Except as contained in this notice, the name of The Open Group shall |
| 23 | not be used in advertising or otherwise to promote the sale, use or |
| 24 | other dealings in this Software without prior written authorization |
| 25 | from The Open Group. |
| 26 | |
| 27 | */ |
| 28 | |
| 29 | /* |
| 30 | * Copyright © 2005 Daniel Stone |
| 31 | * |
| 32 | * Permission to use, copy, modify, distribute, and sell this software and its |
| 33 | * documentation for any purpose is hereby granted without fee, provided that |
| 34 | * the above copyright notice appear in all copies and that both that |
| 35 | * copyright notice and this permission notice appear in supporting |
| 36 | * documentation, and that the name of Daniel Stone not be used in advertising |
| 37 | * or publicity pertaining to distribution of the software without specific, |
| 38 | * written prior permission. Daniel Stone makes no representations about the |
| 39 | * suitability of this software for any purpose. It is provided "as is" |
| 40 | * without express or implied warranty. |
| 41 | * |
| 42 | * DANIEL STONE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
| 43 | * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL |
| 44 | * DANIEL STONE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
| 45 | * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER |
| 46 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 47 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 48 | */ |
| 49 | |
| 50 | #ifndef _XPOLL_H_ |
| 51 | #define _XPOLL_H_ |
| 52 | |
| 53 | #ifndef WIN32 |
| 54 | |
| 55 | #ifndef USE_POLL |
| 56 | |
| 57 | #include <X11/Xos.h> |
| 58 | |
| 59 | #include <sys/select.h> /* Get the FD_* macros. */ |
| 60 | |
| 61 | #include <X11/Xmd.h> |
| 62 | |
| 63 | #ifdef CSRG_BASED |
| 64 | #include <sys/param.h> |
| 65 | # if BSD < 199103 |
| 66 | typedef long fd_mask; |
| 67 | # endif |
| 68 | #endif |
| 69 | |
| 70 | #define XFD_SETSIZE 256 |
| 71 | |
| 72 | #ifndef FD_SETSIZE |
| 73 | #define FD_SETSIZE XFD_SETSIZE |
| 74 | #endif |
| 75 | |
| 76 | #ifndef NBBY |
| 77 | #define NBBY 8 /* number of bits in a byte */ |
| 78 | #endif |
| 79 | |
| 80 | #ifndef NFDBITS |
| 81 | #define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */ |
| 82 | #endif |
| 83 | |
| 84 | #ifndef howmany |
| 85 | #define howmany(x,y) (((x)+((y)-1))/(y)) |
| 86 | #endif |
| 87 | |
| 88 | #if defined(BSD) && BSD < 198911 |
| 89 | typedef struct fd_set { |
| 90 | fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; |
| 91 | } fd_set; |
| 92 | #endif |
| 93 | |
| 94 | # define Select(n,r,w,e,t) select(n,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t) |
| 95 | |
| 96 | #define __X_FDS_BITS __fds_bits |
| 97 | |
| 98 | #ifndef __FDS_BITS |
| 99 | # define __FDS_BITS(p) ((p)->__X_FDS_BITS) |
| 100 | #endif |
| 101 | |
| 102 | #define __XFDS_BITS(p, n) (__FDS_BITS(p))[n] |
| 103 | |
| 104 | #ifndef FD_SET |
| 105 | #define FD_SET(n, p) (__XFDS_BITS(p, ((n)/NFDBITS)) |= ((fd_mask)1 << ((n) % NFDBITS))) |
| 106 | #endif |
| 107 | #ifndef FD_CLR |
| 108 | #define FD_CLR(n, p) (__XFDS_BITS((p), ((n)/NFDBITS)) &= ~((fd_mask)1 << ((n) % NFDBITS))) |
| 109 | #endif |
| 110 | #ifndef FD_ISSET |
| 111 | #define FD_ISSET(n, p) ((__XFDS_BITS((p), ((n)/NFDBITS))) & ((fd_mask)1 << ((n) % NFDBITS))) |
| 112 | #endif |
| 113 | #ifndef FD_ZERO |
| 114 | #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) |
| 115 | #endif |
| 116 | |
| 117 | /* |
| 118 | * The howmany(FD_SETSIZE, NFDBITS) computes the number of elements in the |
| 119 | * array. before accessing an element in the array we check it exists. |
| 120 | * If it does not exist then the compiler discards the code to access it. |
| 121 | */ |
| 122 | #define XFD_ANYSET(p) \ |
| 123 | ((howmany(FD_SETSIZE, NFDBITS) > 0 && (__XFDS_BITS(p, 0))) || \ |
| 124 | (howmany(FD_SETSIZE, NFDBITS) > 1 && (__XFDS_BITS(p, 1))) || \ |
| 125 | (howmany(FD_SETSIZE, NFDBITS) > 2 && (__XFDS_BITS(p, 2))) || \ |
| 126 | (howmany(FD_SETSIZE, NFDBITS) > 3 && (__XFDS_BITS(p, 3))) || \ |
| 127 | (howmany(FD_SETSIZE, NFDBITS) > 4 && (__XFDS_BITS(p, 4))) || \ |
| 128 | (howmany(FD_SETSIZE, NFDBITS) > 5 && (__XFDS_BITS(p, 5))) || \ |
| 129 | (howmany(FD_SETSIZE, NFDBITS) > 6 && (__XFDS_BITS(p, 6))) || \ |
| 130 | (howmany(FD_SETSIZE, NFDBITS) > 7 && (__XFDS_BITS(p, 7)))) |
| 131 | |
| 132 | #define XFD_COPYSET(src,dst) { \ |
| 133 | int __i__; \ |
| 134 | for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ |
| 135 | __XFDS_BITS((dst), __i__) = __XFDS_BITS((src), __i__); \ |
| 136 | } |
| 137 | #define XFD_ANDSET(dst,b1,b2) { \ |
| 138 | int __i__; \ |
| 139 | for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ |
| 140 | __XFDS_BITS((dst), __i__) = ((__XFDS_BITS((b1), __i__)) & (__XFDS_BITS((b2), __i__))); \ |
| 141 | } |
| 142 | #define XFD_ORSET(dst,b1,b2) { \ |
| 143 | int __i__; \ |
| 144 | for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ |
| 145 | __XFDS_BITS((dst), __i__) = ((__XFDS_BITS((b1), __i__)) | (__XFDS_BITS((b2), __i__))); \ |
| 146 | } |
| 147 | #define XFD_UNSET(dst,b1) { \ |
| 148 | int __i__; \ |
| 149 | for (__i__ = 0; __i__ < howmany(FD_SETSIZE, NFDBITS); __i__++) \ |
| 150 | __XFDS_BITS((dst), __i__) &= ~(__XFDS_BITS((b1), __i__)); \ |
| 151 | } |
| 152 | |
| 153 | #else /* USE_POLL */ |
| 154 | #include <sys/poll.h> |
| 155 | #endif /* USE_POLL */ |
| 156 | |
| 157 | #else /* WIN32 */ |
| 158 | |
| 159 | #define XFD_SETSIZE 256 |
| 160 | #ifndef FD_SETSIZE |
| 161 | #define FD_SETSIZE XFD_SETSIZE |
| 162 | #endif |
| 163 | #include <X11/Xwinsock.h> |
| 164 | |
| 165 | #define Select(n,r,w,e,t) select(0,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t) |
| 166 | |
| 167 | #define XFD_SETCOUNT(p) (((fd_set FAR *)(p))->fd_count) |
| 168 | #define XFD_FD(p,i) (((fd_set FAR *)(p))->fd_array[i]) |
| 169 | #define XFD_ANYSET(p) XFD_SETCOUNT(p) |
| 170 | |
| 171 | #define XFD_COPYSET(src,dst) { \ |
| 172 | u_int __i; \ |
| 173 | FD_ZERO(dst); \ |
| 174 | for (__i = 0; __i < XFD_SETCOUNT(src) ; __i++) { \ |
| 175 | XFD_FD(dst,__i) = XFD_FD(src,__i); \ |
| 176 | } \ |
| 177 | XFD_SETCOUNT(dst) = XFD_SETCOUNT(src); \ |
| 178 | } |
| 179 | |
| 180 | #define XFD_ANDSET(dst,b1,b2) { \ |
| 181 | u_int __i; \ |
| 182 | FD_ZERO(dst); \ |
| 183 | for (__i = 0; __i < XFD_SETCOUNT(b1) ; __i++) { \ |
| 184 | if (FD_ISSET(XFD_FD(b1,__i), b2)) \ |
| 185 | FD_SET(XFD_FD(b1,__i), dst); \ |
| 186 | } \ |
| 187 | } |
| 188 | |
| 189 | #define XFD_ORSET(dst,b1,b2) { \ |
| 190 | u_int __i; \ |
| 191 | if (dst != b1) XFD_COPYSET(b1,dst); \ |
| 192 | for (__i = 0; __i < XFD_SETCOUNT(b2) ; __i++) { \ |
| 193 | if (!FD_ISSET(XFD_FD(b2,__i), dst)) \ |
| 194 | FD_SET(XFD_FD(b2,__i), dst); \ |
| 195 | } \ |
| 196 | } |
| 197 | |
| 198 | /* this one is really sub-optimal */ |
| 199 | #define XFD_UNSET(dst,b1) { \ |
| 200 | u_int __i; \ |
| 201 | for (__i = 0; __i < XFD_SETCOUNT(b1) ; __i++) { \ |
| 202 | FD_CLR(XFD_FD(b1,__i), dst); \ |
| 203 | } \ |
| 204 | } |
| 205 | |
| 206 | /* we have to pay the price of having an array here, unlike with bitmasks |
| 207 | calling twice FD_SET with the same fd is not transparent, so be careful */ |
| 208 | #undef FD_SET |
| 209 | #define FD_SET(fd,set) do { \ |
| 210 | if (XFD_SETCOUNT(set) < FD_SETSIZE && !FD_ISSET(fd,set)) \ |
| 211 | XFD_FD(set,XFD_SETCOUNT(set)++)=(fd); \ |
| 212 | } while(0) |
| 213 | |
| 214 | #define getdtablesize() FD_SETSIZE |
| 215 | |
| 216 | #endif /* WIN32 */ |
| 217 | |
| 218 | #endif /* _XPOLL_H_ */ |