}
-static int runtime(verto_profile_t *profile)
+static int profile_one_loop(verto_profile_t *profile)
{
+ switch_waitlist_t pfds[MAX_BIND+4];
+ int res, x = 0;
+ int i = 0;
int max = 2;
+
+ memset(&pfds[0], 0, sizeof(pfds[0]) * MAX_BIND+2);
+
+ for (i = 0; i < profile->i; i++) {
+ pfds[i].sock = profile->server_socket[i];
+ pfds[i].events = SWITCH_POLL_READ|SWITCH_POLL_ERROR;
+ }
+
+ if (profile->mcast_ip) {
+ pfds[i].sock = profile->mcast_sub.sock;
+ pfds[i++].events = SWITCH_POLL_READ|SWITCH_POLL_ERROR;
+ }
+
+ max = i;
+
+ if ((res = switch_wait_socklist(pfds, max, 1000)) < 0) {
+ if (errno != EINTR) {
+ die("POLL FAILED\n");
+ }
+ }
+
+ if (res == 0) {
+ return 0;
+ }
+
+ for (x = 0; x < max; x++) {
+ if (pfds[x].revents & SWITCH_POLL_ERROR) {
+ die("POLL ERROR\n");
+ }
+
+ if (pfds[x].revents & SWITCH_POLL_HUP) {
+ die("POLL HUP\n");
+ }
+
+ if (pfds[x].revents & SWITCH_POLL_READ) {
+ if (pfds[x].sock == profile->mcast_sub.sock) {
+ handle_mcast_sub(profile);
+ } else {
+ start_jsock(profile, pfds[x].sock);
+ }
+ }
+ }
+
+ return res;
+
+ error:
+ return -1;
+}
+
+
+static int runtime(verto_profile_t *profile)
+{
int i;
-
+
for (i = 0; i < profile->i; i++) {
if ((profile->server_socket[i] = prepare_socket(profile->ip[i].local_ip_addr, profile->ip[i].local_port)) < 0) {
die("Client Socket Error!\n");
while(profile->running) {
- struct pollfd pfds[MAX_BIND+4];
- int res, x = 0;
- int i = 0;
-
- memset(&pfds[0], 0, sizeof(pfds[0]) * MAX_BIND+2);
-
- for (i = 0; i < profile->i; i++) {
- pfds[i].fd = profile->server_socket[i];
- pfds[i].events = POLLIN|POLLERR;
- }
-
- if (profile->mcast_ip) {
- pfds[i].fd = profile->mcast_sub.sock;
- pfds[i++].events = POLLIN|POLLERR;
- }
-
- max = i;
-
- if ((res = poll(pfds, max, 1000)) < 0) {
- if (errno != EINTR) {
- die("POLL FAILED\n");
- }
- }
-
- if (res == 0) {
- continue;
- }
-
- for (x = 0; x < max; x++) {
- if (pfds[x].revents & POLLERR) {
- die("POLL ERROR\n");
- }
-
- if (pfds[x].revents & POLLHUP) {
- die("POLL HUP\n");
- }
-
- if (pfds[x].revents & POLLIN) {
- if (pfds[x].fd == profile->mcast_sub.sock) {
- handle_mcast_sub(profile);
- } else {
- start_jsock(profile, pfds[x].fd);
- }
- }
+ if (profile_one_loop(profile) < 0) {
+ goto error;
}
}
}
+SWITCH_DECLARE(int) switch_wait_socklist(switch_waitlist_t *waitlist, uint32_t len, uint32_t ms)
+{
+ struct pollfd *pfds;
+ int s = 0, r = 0, i;
+
+ pfds = calloc(len, sizeof(struct pollfd));
+
+ for (i = 0; i < len; i++) {
+ if (waitlist[i].sock == SWITCH_SOCK_INVALID) {
+ break;
+ }
+
+ pfds[i].fd = waitlist[i].sock;
+
+ if ((waitlist[i].events & SWITCH_POLL_READ)) {
+ pfds[i].events |= POLLIN;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_WRITE)) {
+ pfds[i].events |= POLLOUT;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_ERROR)) {
+ pfds[i].events |= POLLERR;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_HUP)) {
+ pfds[i].events |= POLLHUP;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_RDNORM)) {
+ pfds[i].events |= POLLRDNORM;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_RDBAND)) {
+ pfds[i].events |= POLLRDBAND;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_PRI)) {
+ pfds[i].events |= POLLPRI;
+ }
+ }
+
+ s = poll(pfds, len, ms);
+
+ if (s < 0) {
+ r = s;
+ } else if (s > 0) {
+ for (i = 0; i < len; i++) {
+ if ((pfds[i].revents & POLLIN)) {
+ r |= SWITCH_POLL_READ;
+ waitlist[i].revents |= SWITCH_POLL_READ;
+ }
+ if ((pfds[i].revents & POLLOUT)) {
+ r |= SWITCH_POLL_WRITE;
+ waitlist[i].revents |= SWITCH_POLL_WRITE;
+ }
+ if ((pfds[i].revents & POLLERR)) {
+ r |= SWITCH_POLL_ERROR;
+ waitlist[i].revents |= SWITCH_POLL_ERROR;
+ }
+ if ((pfds[i].revents & POLLHUP)) {
+ r |= SWITCH_POLL_HUP;
+ waitlist[i].revents |= SWITCH_POLL_HUP;
+ }
+ if ((pfds[i].revents & POLLRDNORM)) {
+ r |= SWITCH_POLL_RDNORM;
+ waitlist[i].revents |= SWITCH_POLL_RDNORM;
+ }
+ if ((pfds[i].revents & POLLRDBAND)) {
+ r |= SWITCH_POLL_RDBAND;
+ waitlist[i].revents |= SWITCH_POLL_RDBAND;
+ }
+ if ((pfds[i].revents & POLLPRI)) {
+ r |= SWITCH_POLL_PRI;
+ waitlist[i].revents |= SWITCH_POLL_PRI;
+ }
+ if ((pfds[i].revents & POLLNVAL)) {
+ r |= SWITCH_POLL_INVALID;
+ waitlist[i].revents |= SWITCH_POLL_INVALID;
+ }
+ }
+ }
+
+ return r;
+
+}
+
#else
/* use select instead of poll */
SWITCH_DECLARE(int) switch_wait_sock(switch_os_socket_t sock, uint32_t ms, switch_poll_t flags)
return r;
+}
+
+SWITCH_DECLARE(int) switch_wait_socklist(switch_waitlist_t *waitlist, uint32_t len, uint32_t ms)
+{
+ int s = 0, r = 0;
+ fd_set *rfds;
+ fd_set *wfds;
+ fd_set *efds;
+ struct timeval tv;
+ int i;
+ switch_os_socket_t max_fd = 0;
+ int flags = 0;
+
+ rfds = malloc(sizeof(fd_set));
+ wfds = malloc(sizeof(fd_set));
+ efds = malloc(sizeof(fd_set));
+
+ FD_ZERO(rfds);
+ FD_ZERO(wfds);
+ FD_ZERO(efds);
+
+ for (i = 0; i < len; i++) {
+ if (waitlist[i].sock == SWITCH_SOCK_INVALID) {
+ break;
+ }
+
+ if (waitlist[i].sock > max_fd) {
+ max_fd = waitlist[i].sock;
+ }
+
+#ifndef WIN32
+ /* Wouldn't you rather know?? */
+ assert(waitlist[i].sock <= FD_SETSIZE);
+#endif
+ flags |= waitlist[i].events;
+
+ if ((waitlist[i].events & SWITCH_POLL_READ)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+ FD_SET(waitlist[i].sock, rfds);
+#pragma warning( pop )
+#else
+ FD_SET(waitlist[i].sock, rfds);
+#endif
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_WRITE)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+ FD_SET(waitlist[i].sock, wfds);
+#pragma warning( pop )
+#else
+ FD_SET(waitlist[i].sock, wfds);
+#endif
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_ERROR)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+ FD_SET(waitlist[i].sock, efds);
+#pragma warning( pop )
+#else
+ FD_SET(waitlist[i].sock, efds);
+#endif
+ }
+ }
+
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * ms;
+
+ s = select(max_fd + 1, (flags & SWITCH_POLL_READ) ? rfds : NULL, (flags & SWITCH_POLL_WRITE) ? wfds : NULL, (flags & SWITCH_POLL_ERROR) ? efds : NULL, &tv);
+
+ if (s < 0) {
+ r = s;
+ } else if (s > 0) {
+ for (i = 0; i < len; i++) {
+ if ((waitlist[i].events & SWITCH_POLL_READ) && FD_ISSET(waitlist[i].sock, rfds)) {
+ r |= SWITCH_POLL_READ;
+ waitlist[i].revents |= SWITCH_POLL_READ;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_WRITE) && FD_ISSET(waitlist[i].sock, wfds)) {
+ r |= SWITCH_POLL_WRITE;
+ waitlist[i].revents |= SWITCH_POLL_WRITE;
+ }
+
+ if ((waitlist[i].events & SWITCH_POLL_ERROR) && FD_ISSET(waitlist[i].sock, efds)) {
+ r |= SWITCH_POLL_ERROR;
+ waitlist[i].revents |= SWITCH_POLL_ERROR;
+ }
+ }
+ }
+
+ free(rfds);
+ free(wfds);
+ free(efds);
+
+ return r;
+
}
#endif