version 1.5.8
This commit is contained in:
commit
0598a791bf
153
wepoll.c
153
wepoll.c
@ -29,7 +29,9 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef WEPOLL_EXPORT
|
||||||
#define WEPOLL_EXPORT
|
#define WEPOLL_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@ -110,36 +112,29 @@ WEPOLL_EXPORT int epoll_wait(HANDLE ephnd,
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define WEPOLL_INTERNAL static
|
#define WEPOLL_INTERNAL static
|
||||||
#define WEPOLL_INTERNAL_VAR static
|
#define WEPOLL_INTERNAL_EXTERN static
|
||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#if defined(__clang__)
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
||||||
#pragma clang diagnostic ignored "-Wreserved-id-macro"
|
#pragma clang diagnostic ignored "-Wreserved-id-macro"
|
||||||
#endif
|
#elif defined(_MSC_VER)
|
||||||
|
|
||||||
#ifdef _WIN32_WINNT
|
|
||||||
#undef _WIN32_WINNT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0600
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#pragma warning(push, 1)
|
#pragma warning(push, 1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <WS2tcpip.h>
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <WinSock2.h>
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#undef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0600
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -271,7 +266,7 @@ typedef struct _OBJECT_ATTRIBUTES {
|
|||||||
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status))
|
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status))
|
||||||
|
|
||||||
#define X(return_type, attributes, name, parameters) \
|
#define X(return_type, attributes, name, parameters) \
|
||||||
WEPOLL_INTERNAL_VAR return_type(attributes* name) parameters;
|
WEPOLL_INTERNAL_EXTERN return_type(attributes* name) parameters;
|
||||||
NT_NTDLL_IMPORT_LIST(X)
|
NT_NTDLL_IMPORT_LIST(X)
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
@ -297,13 +292,13 @@ typedef struct _AFD_POLL_INFO {
|
|||||||
AFD_POLL_HANDLE_INFO Handles[1];
|
AFD_POLL_HANDLE_INFO Handles[1];
|
||||||
} AFD_POLL_INFO, *PAFD_POLL_INFO;
|
} AFD_POLL_INFO, *PAFD_POLL_INFO;
|
||||||
|
|
||||||
WEPOLL_INTERNAL int afd_create_helper_handle(HANDLE iocp_handle,
|
WEPOLL_INTERNAL int afd_create_device_handle(HANDLE iocp_handle,
|
||||||
HANDLE* afd_helper_handle_out);
|
HANDLE* afd_device_handle_out);
|
||||||
|
|
||||||
WEPOLL_INTERNAL int afd_poll(HANDLE afd_helper_handle,
|
WEPOLL_INTERNAL int afd_poll(HANDLE afd_device_handle,
|
||||||
AFD_POLL_INFO* poll_info,
|
AFD_POLL_INFO* poll_info,
|
||||||
IO_STATUS_BLOCK* io_status_block);
|
IO_STATUS_BLOCK* io_status_block);
|
||||||
WEPOLL_INTERNAL int afd_cancel_poll(HANDLE afd_helper_handle,
|
WEPOLL_INTERNAL int afd_cancel_poll(HANDLE afd_device_handle,
|
||||||
IO_STATUS_BLOCK* io_status_block);
|
IO_STATUS_BLOCK* io_status_block);
|
||||||
|
|
||||||
#define return_map_error(value) \
|
#define return_map_error(value) \
|
||||||
@ -324,24 +319,24 @@ WEPOLL_INTERNAL int err_check_handle(HANDLE handle);
|
|||||||
|
|
||||||
#define IOCTL_AFD_POLL 0x00012024
|
#define IOCTL_AFD_POLL 0x00012024
|
||||||
|
|
||||||
static UNICODE_STRING afd__helper_name =
|
static UNICODE_STRING afd__device_name =
|
||||||
RTL_CONSTANT_STRING(L"\\Device\\Afd\\Wepoll");
|
RTL_CONSTANT_STRING(L"\\Device\\Afd\\Wepoll");
|
||||||
|
|
||||||
static OBJECT_ATTRIBUTES afd__helper_attributes =
|
static OBJECT_ATTRIBUTES afd__device_attributes =
|
||||||
RTL_CONSTANT_OBJECT_ATTRIBUTES(&afd__helper_name, 0);
|
RTL_CONSTANT_OBJECT_ATTRIBUTES(&afd__device_name, 0);
|
||||||
|
|
||||||
int afd_create_helper_handle(HANDLE iocp_handle,
|
int afd_create_device_handle(HANDLE iocp_handle,
|
||||||
HANDLE* afd_helper_handle_out) {
|
HANDLE* afd_device_handle_out) {
|
||||||
HANDLE afd_helper_handle;
|
HANDLE afd_device_handle;
|
||||||
IO_STATUS_BLOCK iosb;
|
IO_STATUS_BLOCK iosb;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
/* By opening \Device\Afd without specifying any extended attributes, we'll
|
/* By opening \Device\Afd without specifying any extended attributes, we'll
|
||||||
* get a handle that lets us talk to the AFD driver, but that doesn't have an
|
* get a handle that lets us talk to the AFD driver, but that doesn't have an
|
||||||
* associated endpoint (so it's not a socket). */
|
* associated endpoint (so it's not a socket). */
|
||||||
status = NtCreateFile(&afd_helper_handle,
|
status = NtCreateFile(&afd_device_handle,
|
||||||
SYNCHRONIZE,
|
SYNCHRONIZE,
|
||||||
&afd__helper_attributes,
|
&afd__device_attributes,
|
||||||
&iosb,
|
&iosb,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
@ -353,22 +348,22 @@ int afd_create_helper_handle(HANDLE iocp_handle,
|
|||||||
if (status != STATUS_SUCCESS)
|
if (status != STATUS_SUCCESS)
|
||||||
return_set_error(-1, RtlNtStatusToDosError(status));
|
return_set_error(-1, RtlNtStatusToDosError(status));
|
||||||
|
|
||||||
if (CreateIoCompletionPort(afd_helper_handle, iocp_handle, 0, 0) == NULL)
|
if (CreateIoCompletionPort(afd_device_handle, iocp_handle, 0, 0) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!SetFileCompletionNotificationModes(afd_helper_handle,
|
if (!SetFileCompletionNotificationModes(afd_device_handle,
|
||||||
FILE_SKIP_SET_EVENT_ON_HANDLE))
|
FILE_SKIP_SET_EVENT_ON_HANDLE))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
*afd_helper_handle_out = afd_helper_handle;
|
*afd_device_handle_out = afd_device_handle;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
CloseHandle(afd_helper_handle);
|
CloseHandle(afd_device_handle);
|
||||||
return_map_error(-1);
|
return_map_error(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int afd_poll(HANDLE afd_helper_handle,
|
int afd_poll(HANDLE afd_device_handle,
|
||||||
AFD_POLL_INFO* poll_info,
|
AFD_POLL_INFO* poll_info,
|
||||||
IO_STATUS_BLOCK* io_status_block) {
|
IO_STATUS_BLOCK* io_status_block) {
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
@ -377,7 +372,7 @@ int afd_poll(HANDLE afd_helper_handle,
|
|||||||
assert(io_status_block != NULL);
|
assert(io_status_block != NULL);
|
||||||
|
|
||||||
io_status_block->Status = STATUS_PENDING;
|
io_status_block->Status = STATUS_PENDING;
|
||||||
status = NtDeviceIoControlFile(afd_helper_handle,
|
status = NtDeviceIoControlFile(afd_device_handle,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
io_status_block,
|
io_status_block,
|
||||||
@ -396,7 +391,7 @@ int afd_poll(HANDLE afd_helper_handle,
|
|||||||
return_set_error(-1, RtlNtStatusToDosError(status));
|
return_set_error(-1, RtlNtStatusToDosError(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
int afd_cancel_poll(HANDLE afd_helper_handle,
|
int afd_cancel_poll(HANDLE afd_device_handle,
|
||||||
IO_STATUS_BLOCK* io_status_block) {
|
IO_STATUS_BLOCK* io_status_block) {
|
||||||
NTSTATUS cancel_status;
|
NTSTATUS cancel_status;
|
||||||
IO_STATUS_BLOCK cancel_iosb;
|
IO_STATUS_BLOCK cancel_iosb;
|
||||||
@ -407,7 +402,7 @@ int afd_cancel_poll(HANDLE afd_helper_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cancel_status =
|
cancel_status =
|
||||||
NtCancelIoFileEx(afd_helper_handle, io_status_block, &cancel_iosb);
|
NtCancelIoFileEx(afd_device_handle, io_status_block, &cancel_iosb);
|
||||||
|
|
||||||
/* NtCancelIoFileEx() may return STATUS_NOT_FOUND if the operation completed
|
/* NtCancelIoFileEx() may return STATUS_NOT_FOUND if the operation completed
|
||||||
* just before calling NtCancelIoFileEx(). This is not an error. */
|
* just before calling NtCancelIoFileEx(). This is not an error. */
|
||||||
@ -922,7 +917,7 @@ WEPOLL_INTERNAL void poll_group_delete(poll_group_t* poll_group);
|
|||||||
WEPOLL_INTERNAL poll_group_t* poll_group_from_queue_node(
|
WEPOLL_INTERNAL poll_group_t* poll_group_from_queue_node(
|
||||||
queue_node_t* queue_node);
|
queue_node_t* queue_node);
|
||||||
WEPOLL_INTERNAL HANDLE
|
WEPOLL_INTERNAL HANDLE
|
||||||
poll_group_get_afd_helper_handle(poll_group_t* poll_group);
|
poll_group_get_afd_device_handle(poll_group_t* poll_group);
|
||||||
|
|
||||||
typedef struct queue_node {
|
typedef struct queue_node {
|
||||||
queue_node_t* prev;
|
queue_node_t* prev;
|
||||||
@ -948,12 +943,12 @@ WEPOLL_INTERNAL void queue_remove(queue_node_t* node);
|
|||||||
WEPOLL_INTERNAL bool queue_is_empty(const queue_t* queue);
|
WEPOLL_INTERNAL bool queue_is_empty(const queue_t* queue);
|
||||||
WEPOLL_INTERNAL bool queue_is_enqueued(const queue_node_t* node);
|
WEPOLL_INTERNAL bool queue_is_enqueued(const queue_node_t* node);
|
||||||
|
|
||||||
static const size_t POLL_GROUP__MAX_GROUP_SIZE = 32;
|
#define POLL_GROUP__MAX_GROUP_SIZE 32
|
||||||
|
|
||||||
typedef struct poll_group {
|
typedef struct poll_group {
|
||||||
port_state_t* port_state;
|
port_state_t* port_state;
|
||||||
queue_node_t queue_node;
|
queue_node_t queue_node;
|
||||||
HANDLE afd_helper_handle;
|
HANDLE afd_device_handle;
|
||||||
size_t group_size;
|
size_t group_size;
|
||||||
} poll_group_t;
|
} poll_group_t;
|
||||||
|
|
||||||
@ -970,7 +965,7 @@ static poll_group_t* poll_group__new(port_state_t* port_state) {
|
|||||||
queue_node_init(&poll_group->queue_node);
|
queue_node_init(&poll_group->queue_node);
|
||||||
poll_group->port_state = port_state;
|
poll_group->port_state = port_state;
|
||||||
|
|
||||||
if (afd_create_helper_handle(iocp_handle, &poll_group->afd_helper_handle) <
|
if (afd_create_device_handle(iocp_handle, &poll_group->afd_device_handle) <
|
||||||
0) {
|
0) {
|
||||||
free(poll_group);
|
free(poll_group);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -983,7 +978,7 @@ static poll_group_t* poll_group__new(port_state_t* port_state) {
|
|||||||
|
|
||||||
void poll_group_delete(poll_group_t* poll_group) {
|
void poll_group_delete(poll_group_t* poll_group) {
|
||||||
assert(poll_group->group_size == 0);
|
assert(poll_group->group_size == 0);
|
||||||
CloseHandle(poll_group->afd_helper_handle);
|
CloseHandle(poll_group->afd_device_handle);
|
||||||
queue_remove(&poll_group->queue_node);
|
queue_remove(&poll_group->queue_node);
|
||||||
free(poll_group);
|
free(poll_group);
|
||||||
}
|
}
|
||||||
@ -992,8 +987,8 @@ poll_group_t* poll_group_from_queue_node(queue_node_t* queue_node) {
|
|||||||
return container_of(queue_node, poll_group_t, queue_node);
|
return container_of(queue_node, poll_group_t, queue_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE poll_group_get_afd_helper_handle(poll_group_t* poll_group) {
|
HANDLE poll_group_get_afd_device_handle(poll_group_t* poll_group) {
|
||||||
return poll_group->afd_helper_handle;
|
return poll_group->afd_device_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
poll_group_t* poll_group_acquire(port_state_t* port_state) {
|
poll_group_t* poll_group_acquire(port_state_t* port_state) {
|
||||||
@ -1066,7 +1061,7 @@ typedef struct port_state {
|
|||||||
size_t active_poll_count;
|
size_t active_poll_count;
|
||||||
} port_state_t;
|
} port_state_t;
|
||||||
|
|
||||||
static port_state_t* port__alloc(void) {
|
static inline port_state_t* port__alloc(void) {
|
||||||
port_state_t* port_state = malloc(sizeof *port_state);
|
port_state_t* port_state = malloc(sizeof *port_state);
|
||||||
if (port_state == NULL)
|
if (port_state == NULL)
|
||||||
return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY);
|
return_set_error(NULL, ERROR_NOT_ENOUGH_MEMORY);
|
||||||
@ -1074,12 +1069,12 @@ static port_state_t* port__alloc(void) {
|
|||||||
return port_state;
|
return port_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void port__free(port_state_t* port) {
|
static inline void port__free(port_state_t* port) {
|
||||||
assert(port != NULL);
|
assert(port != NULL);
|
||||||
free(port);
|
free(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE port__create_iocp(void) {
|
static inline HANDLE port__create_iocp(void) {
|
||||||
HANDLE iocp_handle =
|
HANDLE iocp_handle =
|
||||||
CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
|
CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
|
||||||
if (iocp_handle == NULL)
|
if (iocp_handle == NULL)
|
||||||
@ -1119,7 +1114,7 @@ err1:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port__close_iocp(port_state_t* port_state) {
|
static inline int port__close_iocp(port_state_t* port_state) {
|
||||||
HANDLE iocp_handle = port_state->iocp_handle;
|
HANDLE iocp_handle = port_state->iocp_handle;
|
||||||
port_state->iocp_handle = NULL;
|
port_state->iocp_handle = NULL;
|
||||||
|
|
||||||
@ -1188,12 +1183,12 @@ static int port__update_events(port_state_t* port_state) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void port__update_events_if_polling(port_state_t* port_state) {
|
static inline void port__update_events_if_polling(port_state_t* port_state) {
|
||||||
if (port_state->active_poll_count > 0)
|
if (port_state->active_poll_count > 0)
|
||||||
port__update_events(port_state);
|
port__update_events(port_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port__feed_events(port_state_t* port_state,
|
static inline int port__feed_events(port_state_t* port_state,
|
||||||
struct epoll_event* epoll_events,
|
struct epoll_event* epoll_events,
|
||||||
OVERLAPPED_ENTRY* iocp_events,
|
OVERLAPPED_ENTRY* iocp_events,
|
||||||
DWORD iocp_event_count) {
|
DWORD iocp_event_count) {
|
||||||
@ -1211,7 +1206,7 @@ static int port__feed_events(port_state_t* port_state,
|
|||||||
return epoll_event_count;
|
return epoll_event_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port__poll(port_state_t* port_state,
|
static inline int port__poll(port_state_t* port_state,
|
||||||
struct epoll_event* epoll_events,
|
struct epoll_event* epoll_events,
|
||||||
OVERLAPPED_ENTRY* iocp_events,
|
OVERLAPPED_ENTRY* iocp_events,
|
||||||
DWORD maxevents,
|
DWORD maxevents,
|
||||||
@ -1321,7 +1316,7 @@ int port_wait(port_state_t* port_state,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port__ctl_add(port_state_t* port_state,
|
static inline int port__ctl_add(port_state_t* port_state,
|
||||||
SOCKET sock,
|
SOCKET sock,
|
||||||
struct epoll_event* ev) {
|
struct epoll_event* ev) {
|
||||||
sock_state_t* sock_state = sock_new(port_state, sock);
|
sock_state_t* sock_state = sock_new(port_state, sock);
|
||||||
@ -1338,7 +1333,7 @@ static int port__ctl_add(port_state_t* port_state,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port__ctl_mod(port_state_t* port_state,
|
static inline int port__ctl_mod(port_state_t* port_state,
|
||||||
SOCKET sock,
|
SOCKET sock,
|
||||||
struct epoll_event* ev) {
|
struct epoll_event* ev) {
|
||||||
sock_state_t* sock_state = port_find_socket(port_state, sock);
|
sock_state_t* sock_state = port_find_socket(port_state, sock);
|
||||||
@ -1353,7 +1348,7 @@ static int port__ctl_mod(port_state_t* port_state,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port__ctl_del(port_state_t* port_state, SOCKET sock) {
|
static inline int port__ctl_del(port_state_t* port_state, SOCKET sock) {
|
||||||
sock_state_t* sock_state = port_find_socket(port_state, sock);
|
sock_state_t* sock_state = port_find_socket(port_state, sock);
|
||||||
if (sock_state == NULL)
|
if (sock_state == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1363,7 +1358,7 @@ static int port__ctl_del(port_state_t* port_state, SOCKET sock) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int port__ctl_op(port_state_t* port_state,
|
static inline int port__ctl_op(port_state_t* port_state,
|
||||||
int op,
|
int op,
|
||||||
SOCKET sock,
|
SOCKET sock,
|
||||||
struct epoll_event* ev) {
|
struct epoll_event* ev) {
|
||||||
@ -1522,11 +1517,11 @@ bool queue_is_enqueued(const queue_node_t* node) {
|
|||||||
return node->prev != node;
|
return node->prev != node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const long REFLOCK__REF = (long) 0x00000001;
|
#define REFLOCK__REF ((long) 0x00000001UL)
|
||||||
static const long REFLOCK__REF_MASK = (long) 0x0fffffff;
|
#define REFLOCK__REF_MASK ((long) 0x0fffffffUL)
|
||||||
static const long REFLOCK__DESTROY = (long) 0x10000000;
|
#define REFLOCK__DESTROY ((long) 0x10000000UL)
|
||||||
static const long REFLOCK__DESTROY_MASK = (long) 0xf0000000;
|
#define REFLOCK__DESTROY_MASK ((long) 0xf0000000UL)
|
||||||
static const long REFLOCK__POISON = (long) 0x300dead0;
|
#define REFLOCK__POISON ((long) 0x300dead0UL)
|
||||||
|
|
||||||
static HANDLE reflock__keyed_event = NULL;
|
static HANDLE reflock__keyed_event = NULL;
|
||||||
|
|
||||||
@ -1589,9 +1584,9 @@ void reflock_unref_and_destroy(reflock_t* reflock) {
|
|||||||
assert(state == REFLOCK__DESTROY);
|
assert(state == REFLOCK__DESTROY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t SOCK__KNOWN_EPOLL_EVENTS =
|
#define SOCK__KNOWN_EPOLL_EVENTS \
|
||||||
EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDNORM |
|
(EPOLLIN | EPOLLPRI | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDNORM | \
|
||||||
EPOLLRDBAND | EPOLLWRNORM | EPOLLWRBAND | EPOLLMSG | EPOLLRDHUP;
|
EPOLLRDBAND | EPOLLWRNORM | EPOLLWRBAND | EPOLLMSG | EPOLLRDHUP)
|
||||||
|
|
||||||
typedef enum sock__poll_status {
|
typedef enum sock__poll_status {
|
||||||
SOCK__POLL_IDLE = 0,
|
SOCK__POLL_IDLE = 0,
|
||||||
@ -1621,13 +1616,14 @@ static inline sock_state_t* sock__alloc(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void sock__free(sock_state_t* sock_state) {
|
static inline void sock__free(sock_state_t* sock_state) {
|
||||||
|
assert(sock_state != NULL);
|
||||||
free(sock_state);
|
free(sock_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sock__cancel_poll(sock_state_t* sock_state) {
|
static inline int sock__cancel_poll(sock_state_t* sock_state) {
|
||||||
assert(sock_state->poll_status == SOCK__POLL_PENDING);
|
assert(sock_state->poll_status == SOCK__POLL_PENDING);
|
||||||
|
|
||||||
if (afd_cancel_poll(poll_group_get_afd_helper_handle(sock_state->poll_group),
|
if (afd_cancel_poll(poll_group_get_afd_device_handle(sock_state->poll_group),
|
||||||
&sock_state->io_status_block) < 0)
|
&sock_state->io_status_block) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1719,7 +1715,7 @@ int sock_set_event(port_state_t* port_state,
|
|||||||
const struct epoll_event* ev) {
|
const struct epoll_event* ev) {
|
||||||
/* EPOLLERR and EPOLLHUP are always reported, even when not requested by the
|
/* EPOLLERR and EPOLLHUP are always reported, even when not requested by the
|
||||||
* caller. However they are disabled after a event has been reported for a
|
* caller. However they are disabled after a event has been reported for a
|
||||||
* socket for which the EPOLLONESHOT flag as set. */
|
* socket for which the EPOLLONESHOT flag was set. */
|
||||||
uint32_t events = ev->events | EPOLLERR | EPOLLHUP;
|
uint32_t events = ev->events | EPOLLERR | EPOLLHUP;
|
||||||
|
|
||||||
sock_state->user_events = events;
|
sock_state->user_events = events;
|
||||||
@ -1806,7 +1802,7 @@ int sock_update(port_state_t* port_state, sock_state_t* sock_state) {
|
|||||||
sock_state->poll_info.Handles[0].Events =
|
sock_state->poll_info.Handles[0].Events =
|
||||||
sock__epoll_events_to_afd_events(sock_state->user_events);
|
sock__epoll_events_to_afd_events(sock_state->user_events);
|
||||||
|
|
||||||
if (afd_poll(poll_group_get_afd_helper_handle(sock_state->poll_group),
|
if (afd_poll(poll_group_get_afd_device_handle(sock_state->poll_group),
|
||||||
&sock_state->poll_info,
|
&sock_state->poll_info,
|
||||||
&sock_state->io_status_block) < 0) {
|
&sock_state->io_status_block) < 0) {
|
||||||
switch (GetLastError()) {
|
switch (GetLastError()) {
|
||||||
@ -2241,14 +2237,13 @@ SOCKET ws_get_base_socket(SOCKET socket) {
|
|||||||
* never intercept the `SIO_BASE_HANDLE` ioctl [1], Komodia based LSPs do
|
* never intercept the `SIO_BASE_HANDLE` ioctl [1], Komodia based LSPs do
|
||||||
* so anyway, breaking it, with the apparent intention of preventing LSP
|
* so anyway, breaking it, with the apparent intention of preventing LSP
|
||||||
* bypass [2]. Fortunately they don't handle `SIO_BSP_HANDLE_POLL`, which
|
* bypass [2]. Fortunately they don't handle `SIO_BSP_HANDLE_POLL`, which
|
||||||
* we can use to obtain the socket associated with the next protocol chain
|
* will at least let us obtain the socket associated with the next winsock
|
||||||
* entry. If this succeeds, loop around and call `SIO_BASE_HANDLE` again
|
* protocol chain entry. If this succeeds, loop around and call
|
||||||
* with the retrieved BSP socket to be sure that we actually got all the
|
* `SIO_BASE_HANDLE` again with the returned BSP socket, to make sure that
|
||||||
* way to the base.
|
* we unwrap all layers and retrieve the actual base socket.
|
||||||
* [1] https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls
|
* [1] https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls
|
||||||
* [2] https://www.komodia.com/newwiki/index.php?title=Komodia%27s_Redirector_bug_fixes#Version_2.2.2.6
|
* [2] https://www.komodia.com/newwiki/index.php?title=Komodia%27s_Redirector_bug_fixes#Version_2.2.2.6
|
||||||
*/
|
*/
|
||||||
|
|
||||||
base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BSP_HANDLE_POLL);
|
base_socket = ws__ioctl_get_bsp_socket(socket, SIO_BSP_HANDLE_POLL);
|
||||||
if (base_socket != INVALID_SOCKET && base_socket != socket)
|
if (base_socket != INVALID_SOCKET && base_socket != socket)
|
||||||
socket = base_socket;
|
socket = base_socket;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user