Index: example/io/attach-end.c
===================================================================
--- example/io/attach-end.c	(revision cf535f4b7e7df8ea4f548e58474cfeff6020a817)
+++ example/io/attach-end.c	(revision cf535f4b7e7df8ea4f548e58474cfeff6020a817)
@@ -0,0 +1,106 @@
+/*
+This is an example that users io_uring with attach mode.
+It demonstrates the what happens if the original ring is deleted before the other.
+It uses liburing for simplicity.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <liburing.h>
+
+
+char buffer1[1024];
+char buffer2[1024];
+
+static void test_read(struct io_uring * ring, int fd) {
+	printf("Testing ring %d\n", ring->ring_fd);
+	struct io_uring_sqe * sqe = io_uring_get_sqe(ring);
+	io_uring_prep_read(sqe, fd, buffer2, 1024, 0);
+
+	io_uring_submit(ring);
+
+	struct io_uring_cqe *cqe;
+	int ret = io_uring_wait_cqe(ring, &cqe);
+	if( ret < 0) {
+		fprintf(stderr, "ioring wait failed: (%d) %s\n", -ret, strerror(-ret));
+		exit(EXIT_FAILURE);
+	}
+	io_uring_cqe_seen(ring, cqe);
+
+	ret = memcmp(buffer1, buffer2, 1024);
+	if(ret != 0) {
+		fprintf(stderr, "files are different!\n");
+		exit(EXIT_FAILURE);
+	}
+}
+
+int main() {
+	const char * path = __FILE__;
+
+	int fd = open(path, 0, O_RDONLY);
+	if( fd < 0) {
+		fprintf(stderr, "Can't open file: (%d) %s\n", errno, strerror(errno));
+		return 1;
+	}
+
+	int ret = read(fd, buffer1, 1024);
+	if( ret < 0 ) {
+		fprintf(stderr, "Can't read file: (%d) %s\n", errno, strerror(errno));
+		return 1;
+	}
+
+	struct io_uring first_ring;
+	io_uring_queue_init(8, &first_ring, 0);
+	printf("Created first ring: %d\n", first_ring.ring_fd);
+
+	test_read(&first_ring, fd);
+
+
+	struct io_uring second_ring;
+	struct io_uring_params p;
+	memset(&p, '\0', sizeof(struct io_uring_params));
+	p.flags |= IORING_SETUP_ATTACH_WQ;
+	p.wq_fd = first_ring.ring_fd;
+	io_uring_queue_init_params(8, &second_ring, &p);
+	printf("Attached second ring: %d\n", second_ring.ring_fd);
+
+	test_read(&second_ring, fd);
+
+	printf("Deleting first ring: %d\n", first_ring.ring_fd);
+	io_uring_queue_exit(&first_ring);
+
+	printf("Sleeping (for good measure)\n");
+
+	usleep( 1000000 );
+
+	test_read(&second_ring, fd);
+
+	struct io_uring third_ring;
+	memset(&p, '\0', sizeof(struct io_uring_params));
+	p.flags |= IORING_SETUP_ATTACH_WQ;
+	p.wq_fd = second_ring.ring_fd;
+	io_uring_queue_init_params(8, &third_ring, &p);
+	printf("Attached third ring: %d\n", third_ring.ring_fd);
+
+	test_read(&third_ring, fd);
+
+	printf("Deleting second ring: %d\n", second_ring.ring_fd);
+	io_uring_queue_exit(&second_ring);
+
+	printf("Sleeping (for good measure)\n");
+
+	usleep( 1000000 );
+
+	io_uring_queue_exit(&third_ring);
+
+	close(fd);
+
+	return 0;
+
+}
