@@ -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);
+
/*! @} */
@@ -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)
+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();
+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 */
From: Holger Hans Peter Freyther <holger@moiji-mobile.com> 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. --- include/osmocom/core/select.h | 6 ++++ src/select.c | 83 ++++++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 32 deletions(-)