src: major refactor
This commit is contained in:
parent
67265bf826
commit
89099e3103
@ -73,7 +73,7 @@ int afd_poll(SOCKET socket, AFD_POLL_INFO* info, OVERLAPPED* overlapped) {
|
||||
}
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
return_success(0);
|
||||
return 0;
|
||||
else if (status == STATUS_PENDING)
|
||||
return_error(-1, ERROR_IO_PENDING);
|
||||
else
|
||||
|
||||
847
src/epoll.c
847
src/epoll.c
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,3 @@ void we_set_win_error(DWORD error) {
|
||||
SetLastError(error);
|
||||
errno = we_map_win_error_to_errno(error);
|
||||
}
|
||||
|
||||
void we_clear_win_error(void) {
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
16
src/error.h
16
src/error.h
@ -10,20 +10,14 @@ DWORD we_map_ntstatus_to_ws_error(NTSTATUS ntstatus);
|
||||
errno_t we_map_win_error_to_errno(DWORD error);
|
||||
|
||||
void we_set_win_error(DWORD error);
|
||||
void we_clear_win_error(void);
|
||||
|
||||
#define _return_error_helper(error, value) \
|
||||
do { \
|
||||
we_set_win_error(error); \
|
||||
return (value); \
|
||||
#define _return_error_helper(error, value) \
|
||||
do { \
|
||||
we_set_win_error(error); \
|
||||
/* { printf("%d\n", error); DebugBreak(); } */ \
|
||||
return (value); \
|
||||
} while (0)
|
||||
|
||||
#define return_error(value, ...) _return_error_helper(__VA_ARGS__ + 0, value)
|
||||
|
||||
#define return_success(value) \
|
||||
do { \
|
||||
we_clear_win_error(); \
|
||||
return (value); \
|
||||
} while (0)
|
||||
|
||||
#endif /* ERROR_H_ */
|
||||
|
||||
99
src/queue.h
Normal file
99
src/queue.h
Normal file
@ -0,0 +1,99 @@
|
||||
/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef QUEUE_H_
|
||||
#define QUEUE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef void* QUEUE[2];
|
||||
|
||||
/* Private macros. */
|
||||
#define QUEUE_NEXT(q) (*(QUEUE**) &((*(q))[0]))
|
||||
#define QUEUE_PREV(q) (*(QUEUE**) &((*(q))[1]))
|
||||
#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q)))
|
||||
#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q)))
|
||||
|
||||
/* Public macros. */
|
||||
#define QUEUE_DATA(ptr, type, field) \
|
||||
((type*) ((char*) (ptr) -offsetof(type, field)))
|
||||
|
||||
/* Important note: mutating the list while QUEUE_FOREACH is
|
||||
* iterating over its elements results in undefined behavior.
|
||||
*/
|
||||
#define QUEUE_FOREACH(q, h) \
|
||||
for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))
|
||||
|
||||
#define QUEUE_EMPTY(q) ((const QUEUE*) (q) == (const QUEUE*) QUEUE_NEXT(q))
|
||||
|
||||
#define QUEUE_HEAD(q) (QUEUE_NEXT(q))
|
||||
|
||||
#define QUEUE_INIT(q) \
|
||||
do { \
|
||||
QUEUE_NEXT(q) = (q); \
|
||||
QUEUE_PREV(q) = (q); \
|
||||
} while (0)
|
||||
|
||||
#define QUEUE_ADD(h, n) \
|
||||
do { \
|
||||
QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \
|
||||
QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \
|
||||
QUEUE_PREV(h) = QUEUE_PREV(n); \
|
||||
QUEUE_PREV_NEXT(h) = (h); \
|
||||
} while (0)
|
||||
|
||||
#define QUEUE_SPLIT(h, q, n) \
|
||||
do { \
|
||||
QUEUE_PREV(n) = QUEUE_PREV(h); \
|
||||
QUEUE_PREV_NEXT(n) = (n); \
|
||||
QUEUE_NEXT(n) = (q); \
|
||||
QUEUE_PREV(h) = QUEUE_PREV(q); \
|
||||
QUEUE_PREV_NEXT(h) = (h); \
|
||||
QUEUE_PREV(q) = (n); \
|
||||
} while (0)
|
||||
|
||||
#define QUEUE_MOVE(h, n) \
|
||||
do { \
|
||||
if (QUEUE_EMPTY(h)) \
|
||||
QUEUE_INIT(n); \
|
||||
else { \
|
||||
QUEUE* q = QUEUE_HEAD(h); \
|
||||
QUEUE_SPLIT(h, q, n); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define QUEUE_INSERT_HEAD(h, q) \
|
||||
do { \
|
||||
QUEUE_NEXT(q) = QUEUE_NEXT(h); \
|
||||
QUEUE_PREV(q) = (h); \
|
||||
QUEUE_NEXT_PREV(q) = (q); \
|
||||
QUEUE_NEXT(h) = (q); \
|
||||
} while (0)
|
||||
|
||||
#define QUEUE_INSERT_TAIL(h, q) \
|
||||
do { \
|
||||
QUEUE_NEXT(q) = (h); \
|
||||
QUEUE_PREV(q) = QUEUE_PREV(h); \
|
||||
QUEUE_PREV_NEXT(q) = (q); \
|
||||
QUEUE_PREV(h) = (q); \
|
||||
} while (0)
|
||||
|
||||
#define QUEUE_REMOVE(q) \
|
||||
do { \
|
||||
QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \
|
||||
QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \
|
||||
} while (0)
|
||||
|
||||
#endif /* QUEUE_H_ */
|
||||
@ -1,12 +1,14 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "win.h"
|
||||
#include "error.h"
|
||||
#include "epoll.h"
|
||||
|
||||
static const char PING[] = "PING";
|
||||
static const int NUM_PINGERS = 1000;
|
||||
static const DWORD RUN_TIME = 10000;
|
||||
static const int NUM_PINGERS = 10000;
|
||||
static const DWORD RUN_TIME = 40000;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
epoll_t epoll_hnd;
|
||||
@ -61,13 +63,17 @@ int main(int argc, char* argv[]) {
|
||||
r = ioctlsocket(sock, FIONBIO, &one);
|
||||
assert(r == 0);
|
||||
|
||||
int one = 1;
|
||||
r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
|
||||
assert(r == 0);
|
||||
|
||||
r = connect(sock, (struct sockaddr*) &addr, sizeof addr);
|
||||
/* Unlike unix, windows sets the error to EWOULDBLOCK when the connection
|
||||
* is being established in the background.
|
||||
*/
|
||||
assert(r == 0 || WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
|
||||
ev.events = EPOLLOUT | EPOLLERR;
|
||||
ev.events = EPOLLOUT | EPOLLERR | EPOLLONESHOT;
|
||||
ev.data.sock = sock;
|
||||
r = epoll_ctl(epoll_hnd, EPOLL_CTL_ADD, sock, &ev);
|
||||
assert(r == 0);
|
||||
@ -147,10 +153,20 @@ int main(int argc, char* argv[]) {
|
||||
wsa_buf.buf = (char*) PING;
|
||||
wsa_buf.len = sizeof PING;
|
||||
r = WSASend(sock, &wsa_buf, 1, &bytes, 0, NULL, NULL);
|
||||
we_set_win_error(0);
|
||||
if (r < 0) perror("send");
|
||||
assert(r >= 0);
|
||||
assert(bytes == sizeof PING);
|
||||
|
||||
pings_sent++;
|
||||
|
||||
uint32_t rev = rand() & 0xff | EPOLLOUT | EPOLLONESHOT;
|
||||
struct epoll_event e;
|
||||
e.data.sock = sock;
|
||||
e.events = rev;
|
||||
if (epoll_ctl(epoll_hnd, EPOLL_CTL_ADD, sock, &e) < 0)
|
||||
abort();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user