1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-26 19:39:53 +03:00

Fixed OSX CPU utilization by replacing broken kevent() with select()

This commit is contained in:
Mike Selivanov 2015-07-09 01:11:40 +03:00
parent ff49706373
commit 29d330522d

View File

@ -9124,12 +9124,23 @@ void UnixSetSockEvent(SOCK_EVENT *event)
} }
} }
// This is a helper function for select()
int safe_fd_set(int fd, fd_set* fds, int* max_fd) {
FD_SET(fd, fds);
if (fd > *max_fd) {
*max_fd = fd;
}
return 0;
}
// Execute 'select' for the socket // Execute 'select' for the socket
void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout) void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout)
{ {
#ifdef UNIX_MACOS #ifdef UNIX_MACOS
int kq; fd_set rfds; //read descriptors
struct kevent *kevents; fd_set wfds; //write descriptors
int max_fd = 0; //maximum descriptor id
struct timeval tv; //timeval for timeout
#else // UNIX_MACOS #else // UNIX_MACOS
struct pollfd *p; struct pollfd *p;
#endif // UNIX_MACOS #endif // UNIX_MACOS
@ -9170,8 +9181,8 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
num = num_read_total + num_write_total; num = num_read_total + num_write_total;
#ifdef UNIX_MACOS #ifdef UNIX_MACOS
kq = kqueue(); FD_ZERO(&rfds); //zero out descriptor set for read descriptors
kevents = ZeroMallocFast(sizeof(struct kevent) * (num + num_write_total)); FD_ZERO(&wfds); //same for write
#else // UNIX_MACOS #else // UNIX_MACOS
p = ZeroMallocFast(sizeof(struct pollfd) * num); p = ZeroMallocFast(sizeof(struct pollfd) * num);
#endif // UNIX_MACOS #endif // UNIX_MACOS
@ -9183,7 +9194,7 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
if (reads[i] != INVALID_SOCKET) if (reads[i] != INVALID_SOCKET)
{ {
#ifdef UNIX_MACOS #ifdef UNIX_MACOS
EV_SET(&kevents[n++], reads[i], EVFILT_READ, EV_ADD, 0, 0, NULL); safe_fd_set(reads[i], &rfds, &max_fd);
#else // UNIX_MACOS #else // UNIX_MACOS
struct pollfd *pfd = &p[n++]; struct pollfd *pfd = &p[n++];
pfd->fd = reads[i]; pfd->fd = reads[i];
@ -9197,8 +9208,7 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
if (writes[i] != INVALID_SOCKET) if (writes[i] != INVALID_SOCKET)
{ {
#ifdef UNIX_MACOS #ifdef UNIX_MACOS
EV_SET(&kevents[n++], reads[i], EVFILT_READ, EV_ADD, 0, 0, NULL); safe_fd_set(writes[i], &wfds, &max_fd);
EV_SET(&kevents[n++], reads[i], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
#else // UNIX_MACOS #else // UNIX_MACOS
struct pollfd *pfd = &p[n++]; struct pollfd *pfd = &p[n++];
pfd->fd = writes[i]; pfd->fd = writes[i];
@ -9210,15 +9220,14 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
if (num != 0) if (num != 0)
{ {
#ifdef UNIX_MACOS #ifdef UNIX_MACOS
struct timespec kevent_timeout, *p_kevent_timeout;
if (timeout == INFINITE) { if (timeout == INFINITE) {
p_kevent_timeout = NULL; tv.tv_sec = 0;
tv.tv_usec = 0;
} else { } else {
kevent_timeout.tv_sec = timeout / 1000; tv.tv_sec = timeout / 1000;
kevent_timeout.tv_nsec = (timeout % 1000) * 1000000l; tv.tv_usec = (timeout % 1000) * 1000l;
p_kevent_timeout = &kevent_timeout;
} }
kevent(kq, kevents, n, kevents, n, p_kevent_timeout); select(max_fd + 1, &rfds, &wfds, NULL, &tv);
#else // UNIX_MACOS #else // UNIX_MACOS
poll(p, num, timeout == INFINITE ? -1 : (int)timeout); poll(p, num, timeout == INFINITE ? -1 : (int)timeout);
#endif // UNIX_MACOS #endif // UNIX_MACOS
@ -9228,12 +9237,9 @@ void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, U
SleepThread(timeout); SleepThread(timeout);
} }
#ifdef UNIX_MACOS #ifndef UNIX_MACOS
Free(kevents);
close(kq);
#else // UNIX_MACOS
Free(p); Free(p);
#endif // UNIX_MACOS #endif // not UNIX_MACOS
} }
// Clean-up of the socket event // Clean-up of the socket event