00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __AST_SELECT_H
00024 #define __AST_SELECT_H
00025
00026 #include <sys/time.h>
00027 #include <sys/select.h>
00028 #include <errno.h>
00029
00030 #include "asterisk/compat.h"
00031
00032 #ifdef __cplusplus
00033 extern "C" {
00034 #endif
00035
00036 extern unsigned int ast_FD_SETSIZE;
00037
00038 #if !defined(HAVE_VARIABLE_FDSET) && defined(CONFIGURE_RAN_AS_ROOT)
00039 #define ast_fdset fd_set
00040 #else
00041 typedef struct {
00042 TYPEOF_FD_SET_FDS_BITS fds_bits[4096 / SIZEOF_FD_SET_FDS_BITS];
00043 } ast_fdset;
00044
00045 #undef FD_ZERO
00046 #define FD_ZERO(a) \
00047 do { \
00048 TYPEOF_FD_SET_FDS_BITS *bytes = (TYPEOF_FD_SET_FDS_BITS *) a; \
00049 int i; \
00050 for (i = 0; i < sizeof(*(a)) / SIZEOF_FD_SET_FDS_BITS; i++) { \
00051 bytes[i] = 0; \
00052 } \
00053 } while (0)
00054 #undef FD_SET
00055 #define FD_SET(fd, fds) \
00056 do { \
00057 TYPEOF_FD_SET_FDS_BITS *bytes = (TYPEOF_FD_SET_FDS_BITS *) fds; \
00058 if (fd / sizeof(*bytes) + ((fd + 1) % sizeof(*bytes) ? 1 : 0) < sizeof(*(fds))) { \
00059 bytes[fd / (sizeof(*bytes) * 8)] |= ((TYPEOF_FD_SET_FDS_BITS) 1) << (fd % (sizeof(*bytes) * 8)); \
00060 } else { \
00061 fprintf(stderr, "FD %d exceeds the maximum size of ast_fdset!\n", fd); \
00062 } \
00063 } while (0)
00064 #endif
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 static inline int ast_select(int nfds, ast_fdset *rfds, ast_fdset *wfds, ast_fdset *efds, struct timeval *tvp)
00077 {
00078 #ifdef __linux__
00079 return select(nfds, (fd_set *) rfds, (fd_set *) wfds, (fd_set *) efds, tvp);
00080 #else
00081 int save_errno = 0;
00082 if (tvp) {
00083 struct timeval tv, tvstart, tvend, tvlen;
00084 int res;
00085
00086 tv = *tvp;
00087 gettimeofday(&tvstart, NULL);
00088 res = select(nfds, (fd_set *) rfds, (fd_set *) wfds, (fd_set *) efds, tvp);
00089 save_errno = errno;
00090 gettimeofday(&tvend, NULL);
00091 timersub(&tvend, &tvstart, &tvlen);
00092 timersub(&tv, &tvlen, tvp);
00093 if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) {
00094 tvp->tv_sec = 0;
00095 tvp->tv_usec = 0;
00096 }
00097 errno = save_errno;
00098 return res;
00099 }
00100 else
00101 return select(nfds, (fd_set *) rfds, (fd_set *) wfds, (fd_set *) efds, NULL);
00102 #endif
00103 }
00104
00105 #ifdef __cplusplus
00106 }
00107 #endif
00108
00109 #endif