src: major refactor

This commit is contained in:
Bert Belder 2017-09-04 17:55:35 +02:00
parent 67265bf826
commit 89099e3103
6 changed files with 616 additions and 374 deletions

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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
View 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_ */

View File

@ -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;
}