diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..177876f --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +CFLAGS ?= -pthread + +all: example + +example: example.o asyncaddrinfo.o + $(CC) $(CFLAGS) -o example example.o asyncaddrinfo.o + +clean: + rm -f *.o example + +%.o: %.c *.h + $(CC) -c $(CFLAGS) $< -o $@ diff --git a/README.md b/README.md index c881429..5908b10 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,7 @@ Asynchronous version of [getaddrinfo()](http://man7.org/linux/man-pages/man3/get * Signals completion via a single file descriptor * Compatible with select, poll, epoll, or blocking results * Simple API; splits getaddrinfo() into two functions, with a file descriptor in between + +## Use + +See [example.c](https://github.com/flamingcowtv/asyncaddrinfo/blob/master/example.c) diff --git a/example.c b/example.c new file mode 100644 index 0000000..797ee94 --- /dev/null +++ b/example.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "asyncaddrinfo.h" + +int main(int argc, char *argv[]) { + asyncaddrinfo_init(2); + + // These will run in parallel. You can still queue more lookups; they'll run + // on the first available thread. + int fd1 = asyncaddrinfo_resolve("github.com", "https", NULL); + assert(fd1 >= 0); + int fd2 = asyncaddrinfo_resolve("google.com", "https", NULL); + assert(fd2 >= 0); + + // This thread continues while lookups run in parallel. + + // We use epoll here, but you could use poll, select, or just call + // asyncaddrinfo_result() and block. You could also use an event loop library + // like libevent. + int epoll_fd = epoll_create1(0); + assert(epoll_fd >= 0); + + struct epoll_event ev = { + .events = EPOLLIN, + }; + + // See epoll_ctl(2) for details on how to attach pointers to application data. + ev.data.fd = fd1; + assert(!epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd1, &ev)); + + ev.data.fd = fd2; + assert(!epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd2, &ev)); + + + int max_events = 2; + while (max_events) { + struct epoll_event events[max_events]; + int num_events = epoll_wait(epoll_fd, events, max_events, -1); + assert(num_events > 0); + for (int i = 0; i < num_events; i++) { + struct addrinfo *addrs; + int err = asyncaddrinfo_result(events[i].data.fd, &addrs); + if (err) { + // Error; see gai_strerror(err) + } else { + // Success; see addrs + freeaddrinfo(addrs); + } + max_events--; + } + } + + assert(!close(epoll_fd)); + // asyncaddrinfo_result() closes the fds opened by asyncaddrinfo_resolve() + + asyncaddrinfo_cleanup(); +}