From patchwork Mon Mar 21 09:55:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Holger Freyther X-Patchwork-Id: 600026 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by ozlabs.org (Postfix) with ESMTP id 3qTB616lY3z9s5g for ; Mon, 21 Mar 2016 20:55:37 +1100 (AEDT) Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by lists.osmocom.org (Postfix) with ESMTP id D2D3C1B636; Mon, 21 Mar 2016 09:55:35 +0000 (UTC) X-Original-To: openbsc@lists.osmocom.org Delivered-To: openbsc@lists.osmocom.org Received: from gandharva.secretlabs.de (gandharva.secretlabs.de [IPv6:2a01:4f8:161:8201::2:4]) by lists.osmocom.org (Postfix) with ESMTP id DB9691B62D for ; Mon, 21 Mar 2016 09:55:33 +0000 (UTC) Received: from localhost.localdomain (ip5b418565.dynamic.kabel-deutschland.de [91.65.133.101]) by gandharva.secretlabs.de (Postfix) with ESMTPSA id 20A7A72AC7 for ; Mon, 21 Mar 2016 09:55:33 +0000 (UTC) From: Holger hans Peter Freyther To: openbsc@lists.osmocom.org Subject: [PATCH v2] select: Externalize fd_set filling and dispatch Date: Mon, 21 Mar 2016 10:55:38 +0100 Message-Id: <1458554138-2040-1-git-send-email-holger@freyther.de> X-Mailer: git-send-email 2.6.3 X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Development of OpenBSC, OsmoBSC, OsmoNITB, OsmoCSCN" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openbsc-bounces@lists.osmocom.org Sender: "OpenBSC" From: Holger Hans Peter Freyther 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 is 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. Confirmed that inlining has an effect on x86 using Debian's gcc-4.9.2-10 compiler --- include/osmocom/core/select.h | 6 ++++ src/select.c | 83 ++++++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/include/osmocom/core/select.h b/include/osmocom/core/select.h index b6b9e82..d71e903 100644 --- a/include/osmocom/core/select.h +++ b/include/osmocom/core/select.h @@ -39,4 +39,10 @@ int osmo_fd_register(struct osmo_fd *fd); void osmo_fd_unregister(struct osmo_fd *fd); int osmo_select_main(int polling); +/* + * foreign event loop integration + */ +int osmo_fd_fill_fds(void *readset, void *writeset, void *exceptset); +int osmo_fd_disp_fds(void *readset, void *writeset, void *exceptset); + /*! @} */ diff --git a/src/select.c b/src/select.c index 5421c77..5826a4d 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); +} + /*! @} */ #endif /* _HAVE_SYS_SELECT_H */