/** Registration struct, iterators, and main-loop convenience functions * * This file is part of the Pollcat Library. * Copyright (C) 2022 Expatria Technologies Inc. * Contact: Morgan Hughes * * The Pollcat Library is free software: you can redistribute it and/or modify it under * the terms of the the GNU Lesser General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received copies of the GNU General Public License and the GNU Lesser * General Public License along with the Pollcat Library. If not, see * https://www.gnu.org/licenses/ * * vim:ts=4:noexpandtab */ #ifndef _INCLUDE_POLLCAT_STRUCT_H_ #define _INCLUDE_POLLCAT_STRUCT_H_ #include struct pollcat_ops; /** Pollcat object structure */ struct pollcat { void *data; const struct pollcat_ops *ops; struct pollcat *next; }; /** Timer callbacks type takes a single void pointer */ typedef void (* pollcat_service_f)(struct pollcat *); /** Operations structure for a pollcat object */ struct pollcat_ops { /* Prepare function is called before poll(); it's a good place to do things like * accept() incoming connections, or add new file descriptors. */ pollcat_service_f prepare; /* Service function is called after poll(); it's the place to check revents for FDs * and do the appropriate read/write options. */ pollcat_service_f service; }; /** Add a pollcat object to the internal iterator list * * \param cat Pointer to pollcat object */ void pollcat_iter_add (struct pollcat *cat); /** Remove pollcat object from the internal iterator list * * \param cat Pointer to pollcat object */ void pollcat_iter_remove (struct pollcat *cat); /** Reset cursor for internal iterator list */ void pollcat_iter_reset (void); /** Return next pollcat object in internal iterator list * * \return Pointer to next pollcat object in list, or NULL at end of list */ struct pollcat *pollcat_iter_next (void); /** Loop wrapper function * * This should be called as the test in a while() loop in main. Internally it will: * - check whether pollcat_loop_exit() has been called, and return 0 if so * - call pollcat_timer_reduce_timeout() to improve timer latency * - call ops.prepare() on each pollcat object in the internal iterator list * - call pollcat_poll() and optionally save the return value in poll-ret * - call pollcat_timer_dispatch() to dispatch any expired timers * - call ops.service() on each pollcat object in the internal iterator list * - return nonzero for next loop * * \param poll_ret Optional pointer to int for return value from poll() call * * \return nonzero if main loop should continue, 0 if it should break */ int pollcat_loop (int *poll_ret); /** Cause pollcat_loop() to return 0 on its next call only * * \note Each call of pollcat_loop_exit() causes pollcat_loop() to return 0 once; * pollcat_loop() then resets the flag to return nonzero until the next time * pollcat_loop_exit() has been called. This allows the entire main loop to be * wrapped in an outer loop so tasks like updating firmware can be done without * affecting the pollcat loop. */ void pollcat_loop_exit (void); #endif /* _INCLUDE_POLLCAT_STRUCT_H_ */