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_ */ 219