diff options
author | Thorsten Kukuk <kukuk@suse.de> | 2015-08-24 10:39:13 -0400 |
---|---|---|
committer | Steve Dickson <steved@redhat.com> | 2015-08-28 09:08:19 -0400 |
commit | b2c9430f46c4ac848957fb8adaac176a3f6ac03f (patch) | |
tree | 1ec5caf4057960f45df755459b563a73664be506 /src/svc_run.c | |
parent | 1c77f7a869bdea2a34799d774460d1f9983d45f0 (diff) | |
download | ti-rpc-b2c9430f46c4ac848957fb8adaac176a3f6ac03f.tar.gz |
Use poll() instead of select() in svc_run()
TI-RPC is using select() in svc_run(), while glibc and Solaris
are using poll(). This has two drawbacks: poll() is much more efficient
then select(), and with select() we are limited to 1024 open
filehandles.
And applications replacing svc_run on Linux don't work, since they
expect
svc_pollfd and svc_max_pollfd.
Attached patch changes this. It's full backward compatible, API and ABI,
so e.g. current rpcbind will continue to work and compile. The only
problem could arrive, that we can have more than 1024 open filehandles
and applications ignoring higher ones.
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Thorsten Kukuk <kukuk@thkukuk.de>
Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'src/svc_run.c')
-rw-r--r-- | src/svc_run.c | 78 |
1 files changed, 51 insertions, 27 deletions
diff --git a/src/svc_run.c b/src/svc_run.c index 783b1dc..f40314b 100644 --- a/src/svc_run.c +++ b/src/svc_run.c @@ -34,10 +34,11 @@ #include <reentrant.h> #include <err.h> #include <errno.h> -#include <rpc/rpc.h> #include <stdio.h> #include <string.h> #include <unistd.h> +#include <sys/poll.h> + #include <rpc/rpc.h> #include "rpc_com.h" @@ -46,33 +47,54 @@ void svc_run() { - fd_set readfds, cleanfds; - struct timeval timeout; - extern rwlock_t svc_fd_lock; + int i; + struct pollfd *my_pollfd = NULL; + int last_max_pollfd = 0; + + for (;;) { + int max_pollfd = svc_max_pollfd; + if (max_pollfd == 0 && svc_pollfd == NULL) + break; + + if (last_max_pollfd != max_pollfd) + { + struct pollfd *new_pollfd + = realloc (my_pollfd, sizeof (struct pollfd) * max_pollfd); + + if (new_pollfd == NULL) + { + warn ("svc_run: - out of memory"); + break; + } + + my_pollfd = new_pollfd; + last_max_pollfd = max_pollfd; + } + + for (i = 0; i < max_pollfd; ++i) + { + my_pollfd[i].fd = svc_pollfd[i].fd; + my_pollfd[i].events = svc_pollfd[i].events; + my_pollfd[i].revents = 0; + } + switch (i = poll (my_pollfd, max_pollfd, -1)) + { + case -1: + if (errno == EINTR) + continue; + warn ("svc_run: - poll failed"); + break; + case 0: + continue; + default: + svc_getreq_poll (my_pollfd, i); + continue; + } + break; + } - for (;;) { - rwlock_rdlock(&svc_fd_lock); - readfds = svc_fdset; - cleanfds = svc_fdset; - rwlock_unlock(&svc_fd_lock); - timeout.tv_sec = 30; - timeout.tv_usec = 0; - switch (select(svc_maxfd+1, &readfds, NULL, NULL, &timeout)) { - case -1: - FD_ZERO(&readfds); - if (errno == EINTR) { - continue; - } - warn("svc_run: - select failed"); - return; - case 0: - __svc_clean_idle(&cleanfds, 30, FALSE); - continue; - default: - svc_getreqset(&readfds); - } - } + free (my_pollfd); } /* @@ -85,6 +107,8 @@ svc_exit() extern rwlock_t svc_fd_lock; rwlock_wrlock(&svc_fd_lock); - FD_ZERO(&svc_fdset); + free (svc_pollfd); + svc_pollfd = NULL; + svc_max_pollfd = 0; rwlock_unlock(&svc_fd_lock); } |