Coder Social home page Coder Social logo

wepoll's Introduction

wepoll - epoll for windows

This library implements the epoll API for Windows applications. It is fast and scalable, and it closely resembles the API and behavior of Linux' epoll.

Rationale

Unlike Linux, OS X, and many other operating systems, Windows doesn't have a good API for receiving socket state notifications. It only supports the select and WSAPoll APIs, but they don't scale and suffer from other issues.

Using I/O completion ports isn't always practical when software is designed to be cross-platform. Wepoll offers an alternative that is much closer to a drop-in replacement for software that was designed to run on Linux.

Features

  • Can poll 100000s of sockets efficiently.
  • Fully thread-safe.
  • Multiple threads can poll the same epoll port.
  • Sockets can be added to multiple epoll sets.
  • All epoll events (EPOLLIN, EPOLLOUT, EPOLLPRI, EPOLLRDHUP) are supported.
  • Level-triggered and one-shot (EPOLLONESTHOT) modes are supported
  • Trivial to embed: you need only two files.

Limitations

  • Only works with sockets.
  • Edge-triggered (EPOLLET) mode isn't supported.

How to use

The library is distributed as a single source file (wepoll.c) and a single header file (wepoll.h).
Compile the .c file as part of your project, and include the header wherever needed.

Compatibility

  • Requires Windows Vista or higher.
  • Can be compiled with recent versions of MSVC, Clang, and GCC.

API

General remarks

  • The epoll port is a HANDLE, not a file descriptor.
  • All functions set both errno and GetLastError() on failure.
  • For more extensive documentation, see the epoll(7) man page, and the per-function man pages that are linked below.

epoll_create/epoll_create1

HANDLE epoll_create(int size);
HANDLE epoll_create1(int flags);
  • Create a new epoll instance (port).
  • size is ignored but most be greater than zero.
  • flags must be zero as there are no supported flags.
  • Returns NULL on failure.
  • Linux man page

epoll_close

int epoll_close(HANDLE ephnd);
  • Close an epoll port.
  • Do not attempt to close the epoll port with close(), CloseHandle() or closesocket().

epoll_ctl

int epoll_ctl(HANDLE ephnd,
              int op,
              SOCKET sock,
              struct epoll_event* event);
  • Control which socket events are monitored by an epoll port.
  • ephnd must be a HANDLE created by epoll_create() or epoll_create1().
  • op must be one of EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL.
  • sock must be a valid socket created by socket(), WSASocket(), or accept().
  • event should be a pointer to a struct epoll_event.
    If op is EPOLL_CTL_DEL then the event parameter is ignored, and it may be NULL.
  • Returns 0 on success, -1 on failure.
  • It is recommended to always explicitly remove a socket from its epoll set using EPOLL_CTL_DEL before closing it.
    As on Linux, closed sockets are automatically removed from the epoll set, but wepoll may not be able to detect that a socket was closed until the next call to epoll_wait().
  • Linux man page

epoll_wait

int epoll_wait(HANDLE ephnd,
               struct epoll_event* events,
               int maxevents,
               int timeout);
  • Receive socket events from an epoll port.
  • events should point to a caller-allocated array of epoll_event structs, which will receive the reported events.
  • maxevents is the maximum number of events that will be written to the events array, and must be greater than zero.
  • timeout specifies whether to block when no events are immediately available.
    • <0 block indefinitely
    • 0 report any events that are already waiting, but don't block
    • ≥1 block for at most N milliseconds
  • Return value:
    • -1 an error occurred
    • 0 timed out without any events to report
    • ≥1 the number of events stored in the events buffer
  • Linux man page

struct epoll_event

typedef union epoll_data {
  void* ptr;
  int fd;
  uint32_t u32;
  uint64_t u64;
  SOCKET sock;        /* Windows specific */
  HANDLE hnd;         /* Windows specific */
} epoll_data_t;
struct epoll_event {
  uint32_t events;    /* Epoll events and flags */
  epoll_data_t data;  /* User data variable */
};
  • The events field is a bit mask containing the events being monitored/reported, and optional flags.
    Flags are accepted by epoll_ctl(), but they are not reported back by epoll_wait().
  • The data field can be used to associate application-specific information with a socket; its value will be returned unmodified by epoll_wait().
  • Linux man page
Event Description
EPOLLIN incoming data available, or incoming connection ready to be accepted
EPOLLOUT ready to send data, or outgoing connection successfully established
EPOLLRDHUP remote peer initiated graceful socket shutdown
EPOLLPRI out-of-band data available for reading
EPOLLERR socket error1
EPOLLHUP socket hang-up1
EPOLLRDNORM same as EPOLLIN
EPOLLRDBAND same as EPOLLPRI
EPOLLWRNORM same as EPOLLOUT
EPOLLWRBAND same as EPOLLOUT
EPOLLMSG never reported
Flag Description
EPOLLONESHOT report event(s) only once
EPOLLET not supported by wepoll
EPOLLEXCLUSIVE not supported by wepoll
EPOLLWAKEUP not supported by wepoll

1: the EPOLLERR and EPOLLHUP events may always be reported by epoll_wait(), regardless of the event mask that was passed to epoll_ctl().

wepoll's People

Contributors

k0zmo avatar piscisaureus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wepoll's Issues

Windows XP support

Hey,

Is there anyway to add support for Windows XP? Many users still use it here.

Thanks

why use InterlockedAdd,but not _InterlockedExchangeAdd ?

I first learned about WEPOLL project because of libzmq compilation problems, i change InterlockedAdd to InterlockedExchangeAdd , and libzmq can work on x64.

then i read windows docs: interlockedexchangeadd, interlockedadd

InterlockedAdd Architecture is ARM, ARM64
_InterlockedExchangeAdd Architecture is x86, ARM, x64, ARM64

so i want to know why WEPOLL don't use _InterlockedExchangeAdd to support more Architecture?

Edge-triggered

Hello, I am aware that wepoll does clarify EPOLLET is not supported but I am wondering if you could add support for it, I have been looking up online a lot for a Windows function that supports edge-triggered and I can't seem to find any, I was wondering if you knew one and can add support for it in the library. Thanks in advance

compile wepoll failed on vs2010

hi piscisaureus,
My env is vs2010 on win10, I meet link error:
"wepoll.obj : error LNK2019: unresolved external symbol _InterlockedAdd referenced in function _reflock_ref"
what static lib should I add into project?
Many thanks

Multi-Threading problems with epoll_wait

Calling epoll_wait in multi threads without using any thread locks will give each thread the same events so only the first thread will succeed and the rest will fail because the events are already handled in the first thread that executed the events. Now putting thread lock before calling epoll_wait will work but that is not really multi-threading, GetQueuedCompletionStatus/eX should be called by several threads at the same time, without any thread locks before the call so each thread will be in waiting mode (at the same time) for the events to arrive, doing so multi-threading will now make sense as GetQueuedCompletionStatus/eX is designed like this.

too many WSAEWOULDBLOCK with send() function (NB TCP)

Hi,

introduction:
My project is to porting c code (proxy server) for WIN env.
The goal is to minimize modification like using select() etc.., so im try use the WEPOLL API and test how it works.
For some reason im got too many WSAEWOULDBLOCK messages when use the send()..and that happen after EPOLLOUT is set. I know the meaning but after all the epoll_wait function say Im ready to send.
When im test the CPU usage (task manger) send and recv goto 40%.
Im send http post to remote web server (that just reply with the same data...)
total data is 1MB with chunck of 10KB.
the avg message error is about 1300+- for two tcp sockets (sending the same http post...)

**when i put sleep(5) after getting WSAEWOULDBLOCK the CPU usage drop around 15%!
There is anything Im do worng? because its seems to me like the epoll mechanism differents in term of optimization from linux.

thanks a lot.

ACCESS VIOLATION - Writing to nullptr

While working with libzmq, which currently embeds wepoll 1.5.8, i had several crashes due to access violations.
These seem to stem from a special behaviour caused by GetQueuedCompletionStatusEx().

This function sometimes returns success (TRUE), containing a positive completion_count (e.g. 1), but still contain an iocp_events[0].lpOverlapped structure with a NULL value. The function is called in line 1223:
https://github.com/piscisaureus/wepoll/blob/dist/wepoll.c#L1223

Later on, wepoll tries to write to this memory location in line 1842:
https://github.com/piscisaureus/wepoll/blob/dist/wepoll.c#L1842

Attached you can find some screenshots of my debug session:

screenshot1

screenshot2

A fix would be highly appreciated :)

Some suggestions on CMake file

(I really admire your work! It's exactly what we need here.)

  1. I had to add at the end of CMakeLists.txt some installation instructions:

file (GLOB includeFiles "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
INSTALL(FILES ${includeFiles} DESTINATION include)
INSTALL(TARGETS ${DLL_TARGET} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

  1. Ideally, if build produced two libraries, static and dynamic. I needed a static library, so I did dirty conversion:

-set(DLL_TARGET "${HEADER_NAME}.dll")
-add_library(${DLL_TARGET} SHARED ${SOURCES_HEADER} ${SOURCES_SRC} ${SOURCES_SRC_REGULAR})
+set(DLL_TARGET "${HEADER_NAME}")
+add_library(${DLL_TARGET} ${SOURCES_HEADER} ${SOURCES_SRC} ${SOURCES_SRC_REGULAR})

This also allowed removing library source files from linking to tests. Otherwise, they are recompiled for each test.

  1. If you could re-define epoll HANDLE to be SOCKET, it would be easier for {*nix, Windows} portable code. On *nix, you normally define SOCKET as int, and many things become more readable.

  2. I'm attaching minimal
    FindEPoll.cmake.txt file, if you're interested. Just remove .txt suffix from its name.

Seems need to load ws2_32.dll manually

I got a few compile errors on my Windows 10 x64 machine :

wepoll-ba852f.o : error LNK2019: 无法解析的外部符号 __imp_WSAStartup,函数 ws_global_init 中引用了该符号 wepoll-ba852f.o : error LNK2019: 无法解析的外部符号 __imp_WSAIoctl,函数 ws__ioctl_get_bsp_socket 中引用了该符号 hello.exe : fatal error LNK1120: 2 个无法解析的外部命令

then I added this line solved the problem:

#pragma comment (lib, "ws2_32.lib")

I am not familiar with C language through, so is it correct?

Also, I haven't seen WSACleanup() being called in epoll_close(), why is that?

Wepoll loses events

Background

We use two epoll handles; One is used only for EPOLLIN events, the other is used for EPOLLOUT. Both are always used with EPOLLONESHOT.

Each epoll handle has a dedicated thread that runs epoll_wait in a loop, and schedules tasks to run in other threads in response to polled events.

Other threads register interest ops with EPOLL_CTL_ADD, and when the event is polled, deregister interest with EPOLL_CTL_DEL. Any given socket handle can be registered at most once with each of the above epoll handles, once for reading, once for writing.

The problem

Occasionally one of the events doesn't fire, even if the wait conditions are satisfied. When that happens, the socket handle is still registered in port_state->sock_tree in state SOCK__POLL_PENDING.

This happens frequently on Windows 2016, less frequently on Windows 2019 and Windows 10, we haven't observed it yet with Windows 11 or 2022. The problem is reproducible with a piece of code that uses multiple UDP sockets talking over the loopback interface, and on Windows 2016 it usually reproduces within the first few minutes of run time. We haven't been able to produce a minimal reproducer yet.

I'm not sure if it's related, but there's some cross-talk when polling the same socket with 2 epoll handles; I added some extra logging, and found that we frequently receive AFD_POLL_SEND event on the EPOLLIN handle. This happens on all systems, including Windows 11.

How can I troubleshoot it further?

`socket == 0` is wrong

wepoll/wepoll.c

Line 1640 in 0598a79

if (socket == 0 || socket == INVALID_SOCKET)

the windows api specifies If no error occurs, socket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling [WSAGetLastError](https://learn.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsagetlasterror). however does not state if such valid return is non-zero or not

however based on https://stackoverflow.com/questions/2135159/socket-returns-0-in-c-client-server-application

socket CAN and WILL return zero if available (eg, if stdin has been closed)

Only wake up one thread when use SO_REUSEADDR

When I bind multi socket to the same port by SO_REUSEADDR, and one socket per thread. only wake up one thread.
Maybe it's the wrong way I use it? But I use wepoll same as epoll.

Wepoll may lose interest list entries when the OS reuses a socket descriptor

Background:

We are using wepoll in multiple threads; one thread runs epoll_wait in a loop, and schedules completion actions to run in response to received events. Other threads register interest ops using epoll_ctl with EPOLL_CTL_MOD first, and if that fails with ENOENT, retrying with EPOLL_CTL_ADD.
The above scheme usually serves us well, but occasionally some events (usually related to connect) are lost.

The problem:

This happens when the socket we use with connect is assigned the same SOCKET value as a recently closed socket, and the sequence of events is exactly right:

  • old socket is closed
  • new socket is created, connect and epoll_ctl are issued
  • the poller thread receives AFD_POLL_LOCAL_CLOSE for the previous socket, and deletes all state associated with the SOCKET handle.

Normally this reproduces 1 in 10k-100k times. By adding a Sleep(30) before this line we can make it reproduce every time.

Can this be fixed in wepoll, or do we need to change the way we use it?

LSP compatibility

Huibertje, is wepoll expected to work in the presence of LSPs? I suspect the answer is 'no' and in that case the readme could list that under 'Limitations.'

Is it safe to remove all lock related codes ?

I am porting a multi threaded shared-nothing tcp server based on epoll to windows . Every thread has its own epoll (IOCP) , a master thread listens for incoming connections and accepts and distributes connections between worker threads.
Is it safe to remove all lock related codes in wepoll to improve performance in this case??

typedef struct ts_tree {
tree_t tree;
SRWLOCK lock; <---
} ts_tree_t;

typedef struct ts_tree_node {
tree_node_t tree_node;
reflock_t reflock; <---
} ts_tree_node_t;

typedef struct port_state {
HANDLE iocp;
tree_t sock_tree;
queue_t sock_update_queue;
queue_t sock_deleted_queue;
queue_t poll_group_queue;
ts_tree_node_t handle_tree_node;
CRITICAL_SECTION lock; <---
size_t active_poll_count;
} port_state_t;

Add support for polling HANDLEs

HANDLEs are used for waitable timers, named pipes, various synchronization primitives, event objects and various other "pollable" things on Windows. Would be nice to be able to poll them in addition to SOCKET.

WSAPoll has been fixed

(If this issue was already discussed, I am really sorry.)

Since WSAPoll has been fixed in recent Windows 10 versions, could this library use an implementation based on it if the Windows 10 build is recent enough ? Since IOCP seems to suffer from latency, the performances should be better.

• At one time, Google Chrome utilized WSAPoll instead of IOCP. (python-trio/trio#52)
• At one time, IOCP suffered from latency. (python-trio/trio#52)
• WSAPoll fix : "As of Windows 10 version 2004, when a TCP socket fails to connect, (POLLHUP | POLLERR | POLLWRNORM) is indicated." (https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll)

Actually, it just an idea. Some of my informations are not up to date. I don't know if Google Chrome uses WSAPoll today, and how they could use it. I don't know if the latency in IOCP has been fixed. I don't know if WSAPoll is more powerful than IOCP in the real world. Nobody opened an issue about this, and I wanted to know the maintainers's thoughts at this moment, since the popularity of Windows 10 is increasing. Someone could use this idea.

Some things to do for greater insight :
• Look up the Google Chrome source code, to see their method.
• Benchmark IOCP vs WSAPoll on Windows 10 version XXXX.

(English isn't my first language, so please excuse any mistakes.)

win x64 sdk:10.0.18362.0 + VS2019, Udp-svr EPOLLIN WSARecvFrom and Tcp-client EPOLLIN WSARecv() both return(-1) and errno(112), not work?

// test-multi-poll.c
#include <process.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "test-util.h"
#include "util.h"
#include "wepoll.h"
#include "win.h"

#define PORT_COUNT 10
#define THREADS_PER_PORT 2

#define LISTEN_PORT 12345

typedef struct test_context {
SOCKET sock;
HANDLE port;
uint64_t data;
HANDLE thread;
} test_context_t;

static SOCKET create_socket(unsigned short port) {
SOCKET sock;
struct sockaddr_in address;
unsigned long one = 1;
int r;

sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
check(sock > 0);

address.sin_family = AF_INET;
address.sin_port = htons(port);
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
r = bind(sock, (struct sockaddr*) &address, sizeof address);
check(r == 0);

r = ioctlsocket(sock, (long) FIONBIO, &one);
check(r == 0);

return sock;
}

static void send_message(SOCKET sock, unsigned short port) {
char hello[] = "hello";
struct sockaddr_in address;
WSABUF buf;
DWORD bytes_sent;
int r;

address.sin_family = AF_INET;
address.sin_port = htons(port);
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

buf.buf = hello;
buf.len = sizeof(hello);

r = WSASendTo(sock,
&buf,
1,
&bytes_sent,
0,
(struct sockaddr*) &address,
sizeof address,
NULL,
NULL);
check(r >= 0);
}

static unsigned int __stdcall poll_thread(void* arg) {
test_context_t* context = arg;
struct epoll_event ev_out;
struct sockaddr_in adr_ss;
int adr_len = sizeof(struct sockaddr_in);
WSABUF rcvbuf = {0};
DWORD count = 0;
int r;

memset(&ev_out, 0, sizeof ev_out);
r = epoll_wait(context->port, &ev_out, 1, -1);
check(r == 1);

check(ev_out.events == EPOLLIN);
check(ev_out.data.u64 == context->data);

printf("Got event (port %p, thread %p)\n", context->port, context->thread);

rcvbuf.len = 100;
rcvbuf.buf = malloc(sizeof(CHAR) * rcvbuf.len);
memset(rcvbuf.buf, 0x00, sizeof(CHAR) * rcvbuf.len);

r = WSARecvFrom(context->sock, &rcvbuf, 1, &count, NULL, (struct sockaddr*)&adr_ss, &adr_len, NULL, NULL);

printf("WSARecvFrom (port %p, thread %p) -> [r:%d,c:%lu]={%s}\n", context->port, context->thread, r, count, rcvbuf.buf);

free(rcvbuf.buf);

return 0;
}

int main(void) {
HANDLE ports[PORT_COUNT];
test_context_t contexts[PORT_COUNT][THREADS_PER_PORT];
WSADATA wsa_data;
size_t i, j;
int r;

/* Initialize winsock. */
r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
check(r == 0);

SOCKET send_sock = create_socket(0);
SOCKET recv_sock = create_socket(LISTEN_PORT);

/* Create PORT_COUNT epoll ports which, will be polled by THREADS_PER_PORT

  • threads. */
    for (i = 0; i < array_count(contexts); i++) {
    HANDLE port;
    struct epoll_event ev;
/* Create epoll port. */
port = epoll_create1(0);
check(port != NULL);
ports[i] = port;

/* Register recv_sock with the epoll port. */
ev.events = EPOLLIN;
ev.data.u64 = (uint64_t) rand();
r = epoll_ctl(port, EPOLL_CTL_ADD, recv_sock, &ev);
check(r == 0);

/* Start THREADS_PER_PORT threads which will all poll the port. */
for (j = 0; j < array_count(contexts[i]); j++) {
  test_context_t* context = &contexts[i][j];
  HANDLE thread;

  /* Prepare context information for the polling thread. */
  context->port = port;
  context->sock = recv_sock;
  context->data = ev.data.u64;

  /* Start thread. */
  thread = (HANDLE) _beginthreadex(
      NULL, 0, poll_thread, (void*) context, 0, NULL);
  check(thread != INVALID_HANDLE_VALUE);
  context->thread = thread;
}

}

/* Sleep for a while to give all threads a chance to finish initializing. */
Sleep(500);

/* Send a message to the receiving socket. */
send_message(send_sock, LISTEN_PORT);

/* Wait for all threads to exit and clean up after them. */
for (i = 0; i < array_count(contexts); i++) {
for (j = 0; j < array_count(contexts[i]); j++) {
HANDLE thread = contexts[i][j].thread;
DWORD wr = WaitForSingleObject(thread, INFINITE);
check(wr == WAIT_OBJECT_0);
CloseHandle(thread);
}
}

/* Close all epoll ports. */
for (i = 0; i < array_count(ports); i++) {
HANDLE port = ports[i];
r = epoll_close(port);
check(r == 0);
}

return 0;
}

// out
E:\GitHub\wepoll\cmake-build-debug\test-multi-poll.exe
Got event (port 0000000000000108, thread 0000000000000114)
Got event (port 0000000000000128, thread 0000000000000130)
WSARecvFrom (port 0000000000000128, thread 0000000000000130) -> [r:-1,c:0]={}
Got event (port 0000000000000148, thread 0000000000000158)
WSARecvFrom (port 0000000000000148, thread 0000000000000158) -> [r:-1,c:0]={}
Got event (port 00000000000000E8, thread 00000000000000F0)
WSARecvFrom (port 00000000000000E8, thread 00000000000000F0) -> [r:-1,c:0]={}
Got event (port 0000000000000160, thread 0000000000000170)
WSARecvFrom (port 0000000000000160, thread 0000000000000170) -> [r:-1,c:0]={}
Got event (port 00000000000000E8, thread 00000000000000F4)
Got event (port 0000000000000160, thread 000000000000016C)
WSARecvFrom (port 0000000000000160, thread 000000000000016C) -> [r:-1,c:0]={}
Got event (port 00000000000000F8, thread 0000000000000100)
WSARecvFrom (port 00000000000000F8, thread 0000000000000100) -> [r:-1,c:0]={}
Got event (port 0000000000000128, thread 0000000000000134)
WSARecvFrom (port 0000000000000128, thread 0000000000000134) -> [r:-1,c:0]={}
Got event (port 0000000000000108, thread 0000000000000110)
WSARecvFrom (port 0000000000000108, thread 0000000000000110) -> [r:-1,c:0]={}
Got event (port 0000000000000138, thread 0000000000000140)
WSARecvFrom (port 0000000000000138, thread 0000000000000140) -> [r:-1,c:0]={}
WSARecvFrom (port 0000000000000108, thread 0000000000000114) -> [r:-1,c:0]={}
Got event (port 0000000000000118, thread 0000000000000124)
Got event (port 0000000000000138, thread 0000000000000144)
Got event (port 0000000000000118, thread 0000000000000120)
Got event (port 0000000000000148, thread 0000000000000154)
WSARecvFrom (port 00000000000000E8, thread 00000000000000F4) -> [r:-1,c:0]={}
Got event (port 00000000000000F8, thread 0000000000000104)
WSARecvFrom (port 00000000000000F8, thread 0000000000000104) -> [r:-1,c:0]={}
Got event (port 00000000000000C8, thread 00000000000000D4)
Got event (port 00000000000000C8, thread 00000000000000D0)
WSARecvFrom (port 00000000000000C8, thread 00000000000000D0) -> [r:-1,c:0]={}
WSARecvFrom (port 0000000000000118, thread 0000000000000124) -> [r:-1,c:0]={}
WSARecvFrom (port 0000000000000138, thread 0000000000000144) -> [r:-1,c:0]={}
WSARecvFrom (port 0000000000000118, thread 0000000000000120) -> [r:-1,c:0]={}
WSARecvFrom (port 0000000000000148, thread 0000000000000154) -> [r:-1,c:0]={}
Got event (port 00000000000000D8, thread 00000000000000E4)
WSARecvFrom (port 00000000000000C8, thread 00000000000000D4) -> [r:-1,c:0]={}
Got event (port 00000000000000D8, thread 00000000000000E0)
WSARecvFrom (port 00000000000000D8, thread 00000000000000E4) -> [r:-1,c:0]={}
WSARecvFrom (port 00000000000000D8, thread 00000000000000E0) -> [r:-1,c:0]={}

Process finished with exit code 0

epoll_ctl: Access Denied

I am trying to run this on Windows Vista, but when I call epoll_ctl I get -1 and the error comming from winapi is Access Denied.
I guess the NtCreateFile function returns with that status.
I am not really sure if this supported on Vista.

wepoll-combined.dll build fails is VC15 2017

Hi,

I generated a solution file using cmake and all the targets except wepoll-combined.dll build.

Project "C:\Users\russh\git\wepoll\build\wepoll-combined.dll.vcxproj.metaproj" (23) is building "C:\Users\russh\git\wepoll\build\wepoll-combined.dll.vcxproj" (24) on
node 1 (default targets).
InitializeBuildStatus:
Touching "wepoll-combined.dll.dir\Debug\wepoll-c.D6E8EA87.tlog\unsuccessfulbuild".
CustomBuild:
Building Custom Rule C:/Users/russh/Git/wepoll/CMakeLists.txt
CMake does not need to re-run because C:/Users/russh/Git/wepoll/build/CMakeFiles/generate.stamp is up-to-date.
Generating dist/wepoll.c
'node' is not recognized as an internal or external command,
operable program or batch file.
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(171,5): error MSB6006: "cmd.exe" exited with code
9009. [C:\Users\russh\git\wepoll\build\wepoll-combined.dll.vcxproj]
Done Building Project "C:\Users\russh\git\wepoll\build\wepoll-combined.dll.vcxproj" (default targets) -- FAILED.

Done Building Project "C:\Users\russh\git\wepoll\build\wepoll-combined.dll.vcxproj.metaproj" (default targets) -- FAILED.

Let me know if you want more details (build steps, full output etc). I'll move forward with the other modules for now I guess? I look forward to trying out wepoll. Thanks!
Russ

WEpoll doesn't compile on VS2017 anymore

WEpoll stopped compiling in the latest Visual Studio 2017.
The error happens on attempt of the compiler detecting CXX 17 compatibility (for C files!):

test-ctl-fuzz.c
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt.h(212): error C2220: warning treated as error - no 'object' file generated
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt.h(212): warning C4668: '__cplusplus' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'

The workaround I used for now was defining at he beginning of each C file:
#define _CRT_HAS_CXX17 0

I guess that should be possible to define in compiler options in CMakeLists.txt file, but I'm not the Windows man so I leave it to pros :)

epoll_wait() gets stuck on Windows 10

I tried a minimal example (an echo server) using wepoll library (v1.3.0). It works well on Windows 7 SP1 (32-bit). But epoll_wait() blocks the program on Windows 10 (1709, 16299.125, 64-bit). I tried to debug using GDB, and it seems GetQueuedCompletionStatusEx gets stuck in _ep_port_poll and never returns (even if I added a finite timeout instead of -1). The compiler is MinGW w64 GCC v7.3.0 (x86_64-w64-mingw32-gcc echo.c wepoll.c -o echo -g -lws2_32). Any idea on the problem? Thanks!

Edit: Same issue on Windows 8.1.

Custom build command for wepoll-sys failed

When trying to compile a project that uses wepoll-sys leads to the following error:

[wepoll-sys 3.0.1] exit code: 0
[wepoll-sys 3.0.1] AR_x86_64-pc-windows-msvc = None
[wepoll-sys 3.0.1] AR_x86_64_pc_windows_msvc = None
[wepoll-sys 3.0.1] HOST_AR = None
[wepoll-sys 3.0.1] AR = None
[wepoll-sys 3.0.1] running: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX64\\x64\\lib.exe" "-out:C:\\Users\\sebir\\Documents\\Programming\\Rust\\GRP-MegaDBtool\\target\\debug\\build\\wepoll-sys-a056e78fbb3b0b9e\\out\\wepoll-build\\libwepoll.a" "-nologo" "C:\\Users\\sebir\\Documents\\Programming\\Rust\\GRP-MegaDBtool\\target\\debug\\build\\wepoll-sys-a056e78fbb3b0b9e\\out\\wepoll-build\\wepoll.o"
[wepoll-sys 3.0.1] LINK : fatal error LNK1181: Eingabedatei "C:\Users\sebir\Documents\Programming\Rust\GRP-MegaDBtool\target\debug\build\wepoll-sys-a056e78fbb3b0b9e\out\wepoll-build\wepoll.o" kann nicht ge�ffnet werden.
[wepoll-sys 3.0.1] exit code: 1181
[wepoll-sys 3.0.1]
[wepoll-sys 3.0.1]
[wepoll-sys 3.0.1] error occurred: Command "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX64\\x64\\lib.exe" "-out:C:\\Users\\sebir\\Documents\\Programming\\Rust\\GRP-MegaDBtool\\target\\debug\\build\\wepoll-sys-a056e78fbb3b0b9e\\out\\wepoll-build\\libwepoll.a" "-nologo" "C:\\Users\\sebir\\Documents\\Programming\\Rust\\GRP-MegaDBtool\\target\\debug\\build\\wepoll-sys-a056e78fbb3b0b9e\\out\\wepoll-build\\wepoll.o" with args "lib.exe" did not execute successfully (status code exit code: 1181).
[wepoll-sys 3.0.1]
[wepoll-sys 3.0.1]
error: failed to run custom build command for `wepoll-sys v3.0.1`

Caused by:
  process didn't exit successfully: `C:\Users\sebir\Documents\Programming\Rust\GRP-MegaDBtool\target\debug\build\wepoll-sys-51f47da9c1c8bc8a\build-script-build` (exit code: 1)
  --- stderr


  error occurred: Command "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX64\\x64\\lib.exe" "-out:C:\\Users\\sebir\\Documents\\Programming\\Rust\\GRP-MegaDBtool\\target\\debug\\build\\wepoll-sys-a056e78fbb3b0b9e\\out\\wepoll-build\\libwepoll.a" "-nologo" "C:\\Users\\sebir\\Documents\\Programming\\Rust\\GRP-MegaDBtool\\target\\debug\\build\\wepoll-sys-a056e78fbb3b0b9e\\out\\wepoll-build\\wepoll.o" with args "lib.exe" did not execute successfully (status code exit code: 1181).

Weird thing is, it works on linux & on my Windows 10 Laptop, which has a nearly identical toolchain setup, but on my Win10 PC it just wont work, neither with msvc or with gnu toolchain

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.