| 1 | /* |
|---|
| 2 | * Resource manager daemon - main loop |
|---|
| 3 | * |
|---|
| 4 | * Copyright (C) 2003 Olaf Kirch <okir@suse.de> |
|---|
| 5 | */ |
|---|
| 6 | |
|---|
| 7 | #ifdef HAVE_CONFIG_H |
|---|
| 8 | #include <config.h> |
|---|
| 9 | #endif |
|---|
| 10 | #include <sys/types.h> |
|---|
| 11 | #include <sys/stat.h> |
|---|
| 12 | #include <sys/poll.h> |
|---|
| 13 | #include <stdio.h> |
|---|
| 14 | #include <stdlib.h> |
|---|
| 15 | #include <string.h> |
|---|
| 16 | #include <unistd.h> |
|---|
| 17 | #include <errno.h> |
|---|
| 18 | |
|---|
| 19 | #include <openct/socket.h> |
|---|
| 20 | #include <openct/server.h> |
|---|
| 21 | #include <openct/logging.h> |
|---|
| 22 | |
|---|
| 23 | #define IFD_MAX_SOCKETS 256 |
|---|
| 24 | |
|---|
| 25 | static ct_socket_t sock_head; |
|---|
| 26 | static int leave_mainloop; |
|---|
| 27 | |
|---|
| 28 | void ct_mainloop_add_socket(ct_socket_t * sock) |
|---|
| 29 | { |
|---|
| 30 | if (sock) |
|---|
| 31 | ct_socket_link(&sock_head, sock); |
|---|
| 32 | } |
|---|
| 33 | |
|---|
| 34 | /* |
|---|
| 35 | * Main loop |
|---|
| 36 | */ |
|---|
| 37 | void ct_mainloop(void) |
|---|
| 38 | { |
|---|
| 39 | leave_mainloop = 0; |
|---|
| 40 | while (!leave_mainloop) { |
|---|
| 41 | struct pollfd pfd[IFD_MAX_SOCKETS + 1]; |
|---|
| 42 | ct_socket_t *poll_socket[IFD_MAX_SOCKETS]; |
|---|
| 43 | ct_socket_t *sock, *next; |
|---|
| 44 | unsigned int nsockets = 0, npoll = 0; |
|---|
| 45 | unsigned int n = 0, listening; |
|---|
| 46 | int have_driver_with_poll = 0; |
|---|
| 47 | int rc; |
|---|
| 48 | |
|---|
| 49 | /* Zap poll structure */ |
|---|
| 50 | memset(pfd, 0, sizeof(pfd)); |
|---|
| 51 | |
|---|
| 52 | /* Count active sockets, and decide whether to |
|---|
| 53 | * accept additional connections or not. */ |
|---|
| 54 | for (sock = sock_head.next; sock; sock = next) { |
|---|
| 55 | next = sock->next; |
|---|
| 56 | /* Kill any dead or excess sockets */ |
|---|
| 57 | if (sock->fd < 0 || nsockets == IFD_MAX_SOCKETS) { |
|---|
| 58 | ct_socket_free(sock); |
|---|
| 59 | } else { |
|---|
| 60 | nsockets++; |
|---|
| 61 | } |
|---|
| 62 | } |
|---|
| 63 | listening = (nsockets < IFD_MAX_SOCKETS) ? POLLIN : 0; |
|---|
| 64 | |
|---|
| 65 | /* Now loop over all sockets and set up the poll structs */ |
|---|
| 66 | for (sock = sock_head.next; sock; sock = sock->next) { |
|---|
| 67 | poll_socket[npoll] = sock; |
|---|
| 68 | if (sock->poll) { |
|---|
| 69 | have_driver_with_poll = 1; |
|---|
| 70 | if (sock->poll(sock, &pfd[npoll]) == 1) |
|---|
| 71 | npoll++; |
|---|
| 72 | } else { |
|---|
| 73 | if (sock->listener) |
|---|
| 74 | sock->events = listening; |
|---|
| 75 | |
|---|
| 76 | pfd[npoll].fd = sock->fd; |
|---|
| 77 | pfd[npoll].events = sock->events; |
|---|
| 78 | npoll++; |
|---|
| 79 | } |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | if (npoll == 0) |
|---|
| 83 | break; |
|---|
| 84 | |
|---|
| 85 | rc = poll(pfd, npoll, have_driver_with_poll ? 1000 : -1); |
|---|
| 86 | if (rc < 0) { |
|---|
| 87 | if (errno == EINTR) |
|---|
| 88 | continue; |
|---|
| 89 | ct_error("poll: %m"); |
|---|
| 90 | break; |
|---|
| 91 | } |
|---|
| 92 | |
|---|
| 93 | for (n = 0; n < npoll; n++) { |
|---|
| 94 | sock = poll_socket[n]; |
|---|
| 95 | if (sock->poll) { |
|---|
| 96 | if (sock->poll(sock, &pfd[n]) < 0) { |
|---|
| 97 | ct_socket_free(sock); |
|---|
| 98 | continue; |
|---|
| 99 | } |
|---|
| 100 | continue; |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | if (pfd[n].revents & POLLERR) { |
|---|
| 104 | if (sock->error(sock) < 0) { |
|---|
| 105 | ct_socket_free(sock); |
|---|
| 106 | continue; |
|---|
| 107 | } |
|---|
| 108 | } |
|---|
| 109 | if (pfd[n].revents & POLLOUT) { |
|---|
| 110 | if (sock->send(sock) < 0) { |
|---|
| 111 | ct_socket_free(sock); |
|---|
| 112 | continue; |
|---|
| 113 | } |
|---|
| 114 | } |
|---|
| 115 | if (pfd[n].revents & POLLIN) { |
|---|
| 116 | if ((rc = sock->recv(sock)) < 0) { |
|---|
| 117 | ct_socket_free(sock); |
|---|
| 118 | continue; |
|---|
| 119 | } |
|---|
| 120 | } |
|---|
| 121 | } |
|---|
| 122 | } |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | void ct_mainloop_leave(void) |
|---|
| 126 | { |
|---|
| 127 | leave_mainloop = 1; |
|---|
| 128 | } |
|---|