Last active
May 22, 2020 22:17
-
-
Save qookei/877ff32f75f722a8bbc3651169a5461a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include <time.h> | |
#include <inttypes.h> | |
#include <unistd.h> | |
#include <atomic> | |
#include <sys/wait.h> | |
void check(int v, const char *reason) { | |
if (v < 0) { | |
fprintf(stderr, "%s failed: %s\n", reason, strerror(errno)); | |
abort(); | |
} | |
} | |
uint64_t current_time_ns() { | |
timespec tv; | |
clock_gettime(CLOCK_MONOTONIC, &tv); | |
return UINT64_C(1000000000) * tv.tv_sec + tv.tv_nsec; | |
} | |
std::atomic_bool do_exit = false; | |
void do_one_send() { | |
int socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); | |
check(socket_fd, "socket"); | |
sockaddr_un server_addr; | |
server_addr.sun_family = AF_UNIX; | |
memcpy(server_addr.sun_path, "\0perf-test!\0", 12); | |
check(connect( | |
socket_fd, | |
reinterpret_cast<sockaddr *>(&server_addr), | |
offsetof(sockaddr_un, sun_path) + 12), "connect"); | |
int recv_size; | |
while (!do_exit) { | |
uint64_t current_time = current_time_ns(); | |
uint8_t message[8]; | |
memcpy(message, ¤t_time, 8); | |
check(send(socket_fd, message, 8, 0), "send"); | |
check((recv_size = recv(socket_fd, message, 8, 0)), "recv"); | |
uint64_t send_time; | |
memcpy(&send_time, message, 8); | |
uint64_t diff = current_time_ns() - send_time; | |
printf("%" PRIu64 "\n", diff); | |
timespec n{.tv_sec = 1, .tv_nsec = 0}; | |
nanosleep(&n, nullptr); | |
} | |
close(socket_fd); | |
} | |
void signal_handler(int) { | |
do_exit = true; | |
} | |
int main() { | |
signal(SIGTERM, signal_handler); | |
while(!do_exit) { | |
timespec n{.tv_sec = 0, .tv_nsec = 1000000}; | |
nanosleep(&n, nullptr); | |
pid_t p = fork(); | |
check(p, "fork"); | |
if (!p) { | |
do_one_send(); | |
return 0; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include <unistd.h> | |
#include <sys/epoll.h> | |
#include <sys/fcntl.h> | |
#include <assert.h> | |
void check(int v, const char *reason) { | |
if (v < 0) { | |
fprintf(stderr, "%s failed: %s\n", reason, strerror(errno)); | |
abort(); | |
} | |
} | |
int main() { | |
int epoll_fd = epoll_create1(0); | |
check(epoll_fd, "epoll_create1"); | |
int socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); | |
check(socket_fd, "socket"); | |
sockaddr_un server_addr; | |
server_addr.sun_family = AF_UNIX; | |
memcpy(server_addr.sun_path, "\0perf-test!\0", 12); | |
check(bind(socket_fd, | |
reinterpret_cast<sockaddr *>(&server_addr), | |
offsetof(sockaddr_un, sun_path) + 12), | |
"bind"); | |
check(listen(socket_fd, 0), "listen"); | |
{ | |
epoll_event ev; | |
ev.events = EPOLLIN; | |
ev.data.fd = socket_fd; | |
check(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &ev), "epoll_ctl(EPOLL_CTL_ADD)"); | |
} | |
printf("Entering main epoll loop...\n"); | |
constexpr size_t max_events = 10; | |
epoll_event events[max_events]; | |
while (true) { | |
int n_fds = epoll_wait(epoll_fd, events, max_events, -1); | |
check(n_fds, "epoll_wait"); | |
for (int i = 0; i < n_fds; i++) { | |
auto fd = events[i].data.fd; | |
if (fd == socket_fd) { | |
sockaddr_un addr; | |
socklen_t len = sizeof(sockaddr_un); | |
int client_fd = accept(socket_fd, | |
reinterpret_cast<sockaddr *>(&addr), | |
&len); | |
check(client_fd, "accept"); | |
int flags=fcntl(client_fd, F_GETFL); | |
fcntl(client_fd, F_SETFL, flags | O_NONBLOCK); | |
epoll_event ev; | |
ev.events = EPOLLHUP | EPOLLIN | EPOLLET; | |
ev.data.fd = client_fd; | |
check(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev), "epoll_ctl(EPOLL_CTL_ADD)"); | |
} else { | |
if (events[i].events & EPOLLHUP) { | |
close(fd); | |
continue; | |
} | |
char buf[1024]; | |
int size = recv(fd, buf, 1024, 0); | |
assert(size > 0); | |
write(fd, buf, size); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment