void Client::check(int timeout) { if(lo_server_wait(_server, timeout)) while(lo_server_recv_noblock(_server, 0)) {} }
void *lo_server_recv_raw_stream(lo_server s, size_t *size) { struct sockaddr_storage addr; socklen_t addr_len = sizeof(addr); char buffer[LO_MAX_MSG_SIZE]; int32_t read_size; int ret=0, i; void *data = NULL; int sock = -1; int repeat = 1; #ifdef HAVE_SELECT #ifndef HAVE_POLL fd_set ps; int nfds=0; #endif #endif /* check sockets in reverse order so that already-open sockets * have priority. this allows checking for closed sockets even * when new connections are being requested. it also allows to * continue looping through the list of sockets after closing and * deleting a socket, since deleting sockets doesn't affect the * order of the array to the left of the index. */ #ifdef HAVE_POLL for (i=0; i < s->sockets_len; i++) { s->sockets[i].events = POLLIN | POLLPRI; s->sockets[i].revents = 0; } poll(s->sockets, s->sockets_len, -1); for (i=(s->sockets_len-1); i >= 0; --i) { if (s->sockets[i].revents == POLLERR || s->sockets[i].revents == POLLHUP) { if (i>0) { close(s->sockets[i].fd); lo_server_del_socket(s, i, s->sockets[i].fd); continue; } else return NULL; } if (s->sockets[i].revents) { sock = s->sockets[i].fd; #else #ifdef HAVE_SELECT if(!initWSock()) return NULL; FD_ZERO(&ps); for (i=(s->sockets_len-1); i >= 0; --i) { FD_SET(s->sockets[i].fd, &ps); if (s->sockets[i].fd > nfds) nfds = s->sockets[i].fd; } if (select(nfds+1,&ps,NULL,NULL,NULL) == SOCKET_ERROR) return NULL; for (i=0; i < s->sockets_len; i++) { if (FD_ISSET(s->sockets[i].fd, &ps)) { sock = s->sockets[i].fd; #endif #endif if (sock == -1 || !repeat) return NULL; /* zeroeth socket is listening for new connections */ if (sock == s->sockets[0].fd) { sock = accept(sock, (struct sockaddr *)&addr, &addr_len); i = lo_server_add_socket(s, sock); /* only repeat this loop for sockets other than the listening * socket, (otherwise i will be wrong next time around) */ repeat = 0; } if (i<0) { close(sock); return NULL; } ret = recv(sock, &read_size, sizeof(read_size), 0); read_size = ntohl(read_size); if (read_size > LO_MAX_MSG_SIZE || ret <= 0) { close(sock); lo_server_del_socket(s, i, sock); if (ret > 0) lo_throw(s, LO_TOOBIG, "Message too large", "recv()"); continue; } ret = recv(sock, buffer, read_size, 0); if (ret <= 0) { close(sock); lo_server_del_socket(s, i, sock); continue; } /* end of loop over sockets: successfully read data */ break; } } data = malloc(ret); memcpy(data, buffer, ret); if (size) *size = ret; return data; } int lo_server_wait(lo_server s, int timeout) { int sched_timeout = lo_server_next_event_delay(s) * 1000; int i; #ifdef HAVE_SELECT #ifndef HAVE_POLL fd_set ps; struct timeval stimeout; #endif #endif #ifdef HAVE_POLL for (i=0; i < s->sockets_len; i++) { s->sockets[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP; s->sockets[i].revents = 0; } poll(s->sockets, s->sockets_len, timeout > sched_timeout ? sched_timeout : timeout); if (lo_server_next_event_delay(s) < 0.01) return 1; for (i=0; i < s->sockets_len; i++) { if (s->sockets[i].revents == POLLERR || s->sockets[i].revents == POLLHUP) return 0; if (s->sockets[i].revents) return 1; } #else #ifdef HAVE_SELECT int res,to,nfds=0; if(!initWSock()) return 0; to = timeout > sched_timeout ? sched_timeout : timeout; stimeout.tv_sec = to/1000; stimeout.tv_usec = (to%1000)*1000; FD_ZERO(&ps); for (i=0; i < s->sockets_len; i++) { FD_SET(s->sockets[i].fd,&ps); if (s->sockets[i].fd > nfds) nfds = s->sockets[i].fd; } res = select(nfds+1,&ps,NULL,NULL,&stimeout); if(res == SOCKET_ERROR) return 0; if (res || lo_server_next_event_delay(s) < 0.01) return 1; #endif #endif return 0; } int lo_server_recv_noblock(lo_server s, int timeout) { int result = lo_server_wait(s,timeout); if (result>0) { return lo_server_recv(s); } else { return 0; } }