port: move ep_port_wait() to port.c

This commit is contained in:
Bert Belder 2017-09-25 19:17:58 +02:00
parent d285bcfab7
commit d3a69678cf
3 changed files with 95 additions and 95 deletions

View File

@ -10,8 +10,6 @@
#include "util.h"
#include "win.h"
#define _EPOLL_MAX_COMPLETION_COUNT 64
static reflock_tree_t _epoll_handle_tree;
static inline ep_port_t* _handle_tree_node_to_port(
@ -145,90 +143,6 @@ int epoll_ctl(HANDLE ephnd, int op, SOCKET sock, struct epoll_event* ev) {
return result;
}
static int _ep_port_poll(ep_port_t* port_info,
struct epoll_event* epoll_events,
OVERLAPPED_ENTRY* iocp_events,
int maxevents,
DWORD timeout) {
ULONG completion_count;
if (ep_port_update_events(port_info) < 0)
return -1;
BOOL r = GetQueuedCompletionStatusEx(port_info->iocp,
iocp_events,
maxevents,
&completion_count,
timeout,
FALSE);
if (!r)
return_error(-1);
return ep_port_feed_events(
port_info, iocp_events, completion_count, epoll_events, maxevents);
}
static int _ep_port_wait(ep_port_t* port_info,
struct epoll_event* events,
int maxevents,
int timeout) {
ULONGLONG due = 0;
DWORD gqcs_timeout;
int result;
/* Check whether `maxevents` is in range. */
if (maxevents <= 0)
return_error(-1, ERROR_INVALID_PARAMETER);
/* Compute how much overlapped entries can be dequeued at most. */
if ((size_t) maxevents > _EPOLL_MAX_COMPLETION_COUNT)
maxevents = _EPOLL_MAX_COMPLETION_COUNT;
/* Compute the timeout for GetQueuedCompletionStatus, and the wait end
* time, if the user specified a timeout other than zero or infinite.
*/
if (timeout > 0) {
due = GetTickCount64() + timeout;
gqcs_timeout = (DWORD) timeout;
} else if (timeout == 0) {
gqcs_timeout = 0;
} else {
gqcs_timeout = INFINITE;
}
/* Dequeue completion packets until either at least one interesting event
* has been discovered, or the timeout is reached.
*/
do {
OVERLAPPED_ENTRY iocp_events[_EPOLL_MAX_COMPLETION_COUNT];
ULONGLONG now;
result =
_ep_port_poll(port_info, events, iocp_events, maxevents, gqcs_timeout);
if (result < 0 || result > 0)
break; /* Result, error, or time-out. */
if (timeout < 0)
continue; /* _ep_port_wait() never times out. */
/* Check for time-out. */
now = GetTickCount64();
if (now >= due)
break;
/* Recompute timeout. */
gqcs_timeout = (DWORD)(due - now);
} while (gqcs_timeout > 0);
if (result >= 0)
return result;
else if (GetLastError() == WAIT_TIMEOUT)
return 0;
else
return -1;
}
int epoll_wait(HANDLE ephnd,
struct epoll_event* events,
int maxevents,
@ -246,7 +160,7 @@ int epoll_wait(HANDLE ephnd,
return_error(-1, ERROR_INVALID_HANDLE);
port_info = _handle_tree_node_to_port(tree_node);
result = _ep_port_wait(port_info, events, maxevents, timeout);
result = ep_port_wait(port_info, events, maxevents, timeout);
reflock_tree_node_unref(tree_node);

View File

@ -12,6 +12,8 @@
#include "util.h"
#include "win.h"
#define _EPOLL_MAX_COMPLETION_COUNT 64
static ep_port_t* _ep_port_alloc(void) {
ep_port_t* port_info = malloc(sizeof *port_info);
if (port_info == NULL)
@ -91,7 +93,7 @@ int ep_port_delete(ep_port_t* port_info) {
return 0;
}
int ep_port_update_events(ep_port_t* port_info) {
static int _ep_port_update_events(ep_port_t* port_info) {
queue_t* update_queue = &port_info->update_queue;
/* Walk the queue, submitting new poll requests for every socket that needs
@ -110,7 +112,7 @@ int ep_port_update_events(ep_port_t* port_info) {
return 0;
}
int ep_port_feed_events(ep_port_t* port_info,
static int _ep_port_feed_events(ep_port_t* port_info,
OVERLAPPED_ENTRY* completion_list,
int completion_count,
struct epoll_event* event_list,
@ -131,6 +133,92 @@ int ep_port_feed_events(ep_port_t* port_info,
return event_count;
}
static int _ep_port_poll(ep_port_t* port_info,
struct epoll_event* epoll_events,
OVERLAPPED_ENTRY* iocp_events,
int maxevents,
DWORD timeout) {
ULONG completion_count;
if (_ep_port_update_events(port_info) < 0)
return -1;
BOOL r = GetQueuedCompletionStatusEx(port_info->iocp,
iocp_events,
maxevents,
&completion_count,
timeout,
FALSE);
if (!r)
return_error(-1);
return _ep_port_feed_events(
port_info, iocp_events, completion_count, epoll_events, maxevents);
}
int ep_port_wait(ep_port_t* port_info,
struct epoll_event* events,
int maxevents,
int timeout) {
ULONGLONG due = 0;
DWORD gqcs_timeout;
int result;
/* Check whether `maxevents` is in range. */
if (maxevents <= 0)
return_error(-1, ERROR_INVALID_PARAMETER);
/* Compute how much overlapped entries can be dequeued at most. */
if ((size_t)maxevents > _EPOLL_MAX_COMPLETION_COUNT)
maxevents = _EPOLL_MAX_COMPLETION_COUNT;
/* Compute the timeout for GetQueuedCompletionStatus, and the wait end
* time, if the user specified a timeout other than zero or infinite.
*/
if (timeout > 0) {
due = GetTickCount64() + timeout;
gqcs_timeout = (DWORD)timeout;
}
else if (timeout == 0) {
gqcs_timeout = 0;
}
else {
gqcs_timeout = INFINITE;
}
/* Dequeue completion packets until either at least one interesting event
* has been discovered, or the timeout is reached.
*/
do {
OVERLAPPED_ENTRY iocp_events[_EPOLL_MAX_COMPLETION_COUNT];
ULONGLONG now;
result =
_ep_port_poll(port_info, events, iocp_events, maxevents, gqcs_timeout);
if (result < 0 || result > 0)
break; /* Result, error, or time-out. */
if (timeout < 0)
continue; /* _ep_port_wait() never times out. */
/* Check for time-out. */
now = GetTickCount64();
if (now >= due)
break;
/* Recompute timeout. */
gqcs_timeout = (DWORD)(due - now);
} while (gqcs_timeout > 0);
if (result >= 0)
return result;
else if (GetLastError() == WAIT_TIMEOUT)
return 0;
else
return -1;
}
int ep_port_add_socket(ep_port_t* port_info,
ep_sock_t* sock_info,
SOCKET socket) {

View File

@ -30,12 +30,10 @@ EPOLL_INTERNAL ep_port_t* ep_port_new(HANDLE iocp);
EPOLL_INTERNAL int ep_port_close(ep_port_t* port_info);
EPOLL_INTERNAL int ep_port_delete(ep_port_t* port_info);
EPOLL_INTERNAL int ep_port_update_events(ep_port_t* port_info);
EPOLL_INTERNAL int ep_port_feed_events(ep_port_t* port_info,
OVERLAPPED_ENTRY* completion_list,
int completion_count,
struct epoll_event* event_list,
int max_event_count);
EPOLL_INTERNAL int ep_port_wait(ep_port_t* port_info,
struct epoll_event* events,
int maxevents,
int timeout);
EPOLL_INTERNAL poll_group_t* ep_port_acquire_poll_group(
ep_port_t* port_info,