The odd thing about rn is that you have to tell it the maximum number of file descriptors you expect to have to use, and (if you want to work with sigio) you have to tell it which realtime signal to use to deliver its notifications.
The epoll library must be installed before you can build rn.
Here are the steps to add rn support to a program currently using poll():
#include <rn.h>to get access to rn.
rn_t rns; if (rn_init(&rns, 128)) { printf("FAIL: rn_init failed \n"); exit(1); } if (rn_setSignum(&rns, SIGRTMIN)) { printf("FAIL: rn_setSignum failed \n"); exit(1); }The second argument to rn_init() should be the highest file descriptor you expect to ever see in your program, or roughly the number of sockets you expect to have open at any one time.
The second argument to rn_setSignum() is the realtime signal rn should use internally. Usually SIGRTMIN is fine.
err = rn_prepare_fd_for_add(fd, getpid()); if (err) { printf("FAIL: rn_prepare_fd_for_add failed, errno %d\n", err); exit(1); } err = rn_add(&rns, fd, my_callback, NULL); if (err) { printf("FAIL: rn_add failed, errno %d\n", err); exit(1); }The third argument to rn_add() is your readiness event handler function; it is called whenever that socket becomes ready for I/O. The fourth argument to rn_add() is for your use; it is a context pointer that will be passed back when your readiness event handler is called. You can use it to hold a pointer to the object associated with that socket. (If there is demand, I may add a C++ wrapper for rn so C++ programmers could simply give an object pointer here, and inherit from class rnClient, then override its virtual readiness event handler method.)
rn_del(&fns, fd);
rn_waitAndDispatchEvents(&rns, timeout_milliseconds);The second argument to rn_waitAndDispatchEvents is the timeout in milliseconds; the call will sleep until some sockets are ready for I/O, but no longer than timeout_milliseconds.
Here's what a successful run looks like:
# ./rn_test fn: revents 4 rn_POLLOUT fn: revents 5 fn: read returns 1024, errno 11 ... (repeats 62 times) fn: read returns 1024, errno 11 fn: read returns 977, errno 11 Read 66513 bytes PASSIf you're debugging a program that uses rn, you may wish to rebuild rn with dprints enabled. To do this, uncomment the lines
/* #define dprint_ENABLED */ /* #define dprint_TRACE_ENABLED */in rn_dprint.h, and rebuild and reinstall rn. With dprint enabled, a successful run looks like this:
# ./rn_test -469985671:47:rn_sys_epoll.c:rn_sys_epoll_init init() -469985652:150:rn_sys_epoll.c:rn_sys_epoll_add add(4, 0x10000954, (nil)) this->m_fds_used 1 -469985651:198:rn_sys_epoll.c:rn_sys_epoll_waitAndDispatchEvents Calling epoll... -469985651:200:rn_sys_epoll.c:rn_sys_epoll_waitAndDispatchEvents epoll returns 1 fds. errno: 11-469985651:213:rn_sys_epoll.c:rn_sys_epoll_waitAndDispatchEvents fd 4, revents 4 fn: revents 4 rn_POLLOUT -469985651:198:rn_sys_epoll.c:rn_sys_epoll_waitAndDispatchEvents Calling epoll... -469985638:200:rn_sys_epoll.c:rn_sys_epoll_waitAndDispatchEvents epoll returns 1 fds. errno: 11-469985638:213:rn_sys_epoll.c:rn_sys_epoll_waitAndDispatchEvents fd 4, revents 5 fn: revents 5 fn: read returns 1024, errno 11 ... (62 lines like the one above) fn: read returns 1024, errno 11 fn: read returns 118, errno 11 Read 65654 bytes -469985628:160:rn_sys_epoll.c:rn_sys_epoll_del del(fd 4) PASS