diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2016-03-21 09:55:05 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2016-03-31 16:56:51 +0200 |
commit | 61f28880d5dc3f08689bef61a54fa2035928ffaa (patch) | |
tree | 04574f58327f38d26b2c9df0ab4f93c236477255 /src | |
parent | fb348eeff25e8e66a4a8651dc94901c7a004343a (diff) |
select: Externalize fd_set filling and dispatch
To integrate with an external event loop (in this case glib) we
need to allow an application to get a filled out fd_set and then
dispatch it. osmo_fds and maxfds are static and I decided to keep
it that way and instead create two routines to fill the fdset and
then one to dispatch the result.
The public header file does not include sys/select.h and we can
compile the library without select, so I didn't want to require
having to include this file, and used void * for the parameter.
Mark the routines as inline to avoid a call from the select
function. I have confirmed that inlining has an effect on x86
using Debian's gcc-4.9.2-10 compiler
Diffstat (limited to 'src')
-rw-r--r-- | src/select.c | 83 |
1 files changed, 51 insertions, 32 deletions
diff --git a/src/select.c b/src/select.c index 477ff662..02bc2cc3 100644 --- a/src/select.c +++ b/src/select.c @@ -98,62 +98,49 @@ void osmo_fd_unregister(struct osmo_fd *fd) llist_del(&fd->list); } -/*! \brief select main loop integration - * \param[in] polling should we pollonly (1) or block on select (0) - */ -int osmo_select_main(int polling) +inline int osmo_fd_fill_fds(void *_rset, void *_wset, void *_eset) { - struct osmo_fd *ufd, *tmp; - fd_set readset, writeset, exceptset; - int work = 0, rc; - struct timeval no_time = {0, 0}; + fd_set *readset = _rset, *writeset = _wset, *exceptset = _eset; + struct osmo_fd *ufd; - FD_ZERO(&readset); - FD_ZERO(&writeset); - FD_ZERO(&exceptset); - - /* prepare read and write fdsets */ llist_for_each_entry(ufd, &osmo_fds, list) { if (ufd->when & BSC_FD_READ) - FD_SET(ufd->fd, &readset); + FD_SET(ufd->fd, readset); if (ufd->when & BSC_FD_WRITE) - FD_SET(ufd->fd, &writeset); + FD_SET(ufd->fd, writeset); if (ufd->when & BSC_FD_EXCEPT) - FD_SET(ufd->fd, &exceptset); + FD_SET(ufd->fd, exceptset); } - osmo_timers_check(); - - if (!polling) - osmo_timers_prepare(); - rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : osmo_timers_nearest()); - if (rc < 0) - return 0; + return maxfd; +} - /* fire timers */ - osmo_timers_update(); +inline int osmo_fd_disp_fds(void *_rset, void *_wset, void *_eset) +{ + struct osmo_fd *ufd, *tmp; + int work = 0; + fd_set *readset = _rset, *writeset = _wset, *exceptset = _eset; - /* call registered callback functions */ restart: unregistered_count = 0; llist_for_each_entry_safe(ufd, tmp, &osmo_fds, list) { int flags = 0; - if (FD_ISSET(ufd->fd, &readset)) { + if (FD_ISSET(ufd->fd, readset)) { flags |= BSC_FD_READ; - FD_CLR(ufd->fd, &readset); + FD_CLR(ufd->fd, readset); } - if (FD_ISSET(ufd->fd, &writeset)) { + if (FD_ISSET(ufd->fd, writeset)) { flags |= BSC_FD_WRITE; - FD_CLR(ufd->fd, &writeset); + FD_CLR(ufd->fd, writeset); } - if (FD_ISSET(ufd->fd, &exceptset)) { + if (FD_ISSET(ufd->fd, exceptset)) { flags |= BSC_FD_EXCEPT; - FD_CLR(ufd->fd, &exceptset); + FD_CLR(ufd->fd, exceptset); } if (flags) { @@ -167,9 +154,41 @@ restart: if (unregistered_count >= 1) goto restart; } + return work; } +/*! \brief select main loop integration + * \param[in] polling should we pollonly (1) or block on select (0) + */ +int osmo_select_main(int polling) +{ + fd_set readset, writeset, exceptset; + int rc; + struct timeval no_time = {0, 0}; + + FD_ZERO(&readset); + FD_ZERO(&writeset); + FD_ZERO(&exceptset); + + /* prepare read and write fdsets */ + osmo_fd_fill_fds(&readset, &writeset, &exceptset); + + osmo_timers_check(); + + if (!polling) + osmo_timers_prepare(); + rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : osmo_timers_nearest()); + if (rc < 0) + return 0; + + /* fire timers */ + osmo_timers_update(); + + /* call registered callback functions */ + return osmo_fd_disp_fds(&readset, &writeset, &exceptset); +} + /*! \brief find an osmo_fd based on the integer fd */ struct osmo_fd *osmo_fd_get_by_fd(int fd) { |