From 796f7837d0ce043f1695f4bae632884dd7e63139 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Mon, 8 Mar 2021 10:24:20 +0100 Subject: [PATCH] moved btstack_run_loop_base into btstack_run_loop to allow for refactored run loops without client build changes --- src/btstack_run_loop.c | 101 ++++++++++++++++++++++++++ src/btstack_run_loop.h | 87 +++++++++++++++++++++- src/btstack_run_loop_base.c | 140 +----------------------------------- src/btstack_run_loop_base.h | 132 +--------------------------------- 4 files changed, 190 insertions(+), 270 deletions(-) diff --git a/src/btstack_run_loop.c b/src/btstack_run_loop.c index b9fdb5f06..c5ce14b3f 100644 --- a/src/btstack_run_loop.c +++ b/src/btstack_run_loop.c @@ -47,11 +47,112 @@ #include "btstack_debug.h" #include "btstack_config.h" +#include "btstack_util.h" static const btstack_run_loop_t * the_run_loop = NULL; extern const btstack_run_loop_t btstack_run_loop_embedded; +/* + * Portable implementation of timer and data source management as base for platform specific implementations + */ + +// private data (access only by run loop implementations) +btstack_linked_list_t btstack_run_loop_base_timers; +btstack_linked_list_t btstack_run_loop_base_data_sources; + +void btstack_run_loop_base_init(void){ + btstack_run_loop_base_timers = NULL; + btstack_run_loop_base_data_sources = NULL; +} + +void btstack_run_loop_base_add_data_source(btstack_data_source_t *ds){ + btstack_linked_list_add(&btstack_run_loop_base_data_sources, (btstack_linked_item_t *) ds); +} + +bool btstack_run_loop_base_remove_data_source(btstack_data_source_t *ds){ + return btstack_linked_list_remove(&btstack_run_loop_base_data_sources, (btstack_linked_item_t *) ds); +} + +void btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * ds, uint16_t callback_types){ + ds->flags |= callback_types; +} + +void btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * ds, uint16_t callback_types){ + ds->flags &= ~callback_types; +} + +bool btstack_run_loop_base_remove_timer(btstack_timer_source_t *ts){ + return btstack_linked_list_remove(&btstack_run_loop_base_timers, (btstack_linked_item_t *) ts); +} + +void btstack_run_loop_base_add_timer(btstack_timer_source_t *ts){ + btstack_linked_item_t *it; + for (it = (btstack_linked_item_t *) &btstack_run_loop_base_timers; it->next ; it = it->next){ + btstack_timer_source_t * next = (btstack_timer_source_t *) it->next; + btstack_assert(next != ts); + int32_t delta = btstack_time_delta(ts->timeout, next->timeout); + if (delta < 0) break; + } + ts->item.next = it->next; + it->next = (btstack_linked_item_t *) ts; +} + +void btstack_run_loop_base_process_timers(uint32_t now){ + // process timers, exit when timeout is in the future + while (btstack_run_loop_base_timers) { + btstack_timer_source_t * ts = (btstack_timer_source_t *) btstack_run_loop_base_timers; + int32_t delta = btstack_time_delta(ts->timeout, now); + if (delta > 0) break; + btstack_run_loop_base_remove_timer(ts); + ts->process(ts); + } +} + +void btstack_run_loop_base_dump_timer(void){ +#ifdef ENABLE_LOG_INFO + btstack_linked_item_t *it; + uint16_t i = 0; + for (it = (btstack_linked_item_t *) btstack_run_loop_base_timers; it ; it = it->next){ + btstack_timer_source_t *ts = (btstack_timer_source_t*) it; + log_info("timer %u (%p): timeout %u\n", i, ts, ts->timeout); + } +#endif + +} +/** + * @brief Get time until first timer fires + * @returns -1 if no timers, time until next timeout otherwise + */ +int32_t btstack_run_loop_base_get_time_until_timeout(uint32_t now){ + if (btstack_run_loop_base_timers == NULL) return -1; + btstack_timer_source_t * ts = (btstack_timer_source_t *) btstack_run_loop_base_timers; + uint32_t list_timeout = ts->timeout; + int32_t delta = btstack_time_delta(list_timeout, now); + if (delta < 0){ + delta = 0; + } + return delta; +} + +void btstack_run_loop_base_poll_data_sources(void){ + // poll data sources + btstack_data_source_t *ds; + btstack_data_source_t *next; + for (ds = (btstack_data_source_t *) btstack_run_loop_base_data_sources; ds != NULL ; ds = next){ + next = (btstack_data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself + if (ds->flags & DATA_SOURCE_CALLBACK_POLL){ + ds->process(ds, DATA_SOURCE_CALLBACK_POLL); + } + } +} + +/** + * BTstack Run Loop Implementation, mainly dispatches to port-specific implementation + */ + +// main implementation + void btstack_run_loop_set_timer_handler(btstack_timer_source_t *ts, void (*process)(btstack_timer_source_t *_ts)){ ts->process = process; }; diff --git a/src/btstack_run_loop.h b/src/btstack_run_loop.h index f138ff034..5d207c096 100644 --- a/src/btstack_run_loop.h +++ b/src/btstack_run_loop.h @@ -108,7 +108,83 @@ typedef struct btstack_run_loop { uint32_t (*get_time_ms)(void); } btstack_run_loop_t; -void btstack_run_loop_timer_dump(void); + +/* + * BTstack Run Loop Base Implementation + * Portable implementation of timer and data source management as base for platform specific implementations + */ + +// private data (access only by run loop implementations) +extern btstack_linked_list_t btstack_run_loop_base_timers; +extern btstack_linked_list_t btstack_run_loop_base_data_sources; + +/** + * @brief Init + */ +void btstack_run_loop_base_init(void); + +/** + * @brief Add timer source. + * @param timer to add + */ +void btstack_run_loop_base_add_timer(btstack_timer_source_t * timer); + +/** + * @brief Remove timer source. + * @param timer to remove + * @returns true if timer was removed + */ +bool btstack_run_loop_base_remove_timer(btstack_timer_source_t * timer); + +/** + * @brief Process timers: remove expired timers from list and call their process function + * @param now + */ +void btstack_run_loop_base_process_timers(uint32_t now); + +/** + * @brief Dump list of timers via log_info + */ +void btstack_run_loop_base_dump_timer(void); + +/** + * @brief Get time until first timer fires + * @returns -1 if no timers, time until next timeout otherwise + */ +int32_t btstack_run_loop_base_get_time_until_timeout(uint32_t now); + +/** + * @brief Add data source to run loop + * @param data_source to add + */ +void btstack_run_loop_base_add_data_source(btstack_data_source_t * data_source); + +/** + * @brief Remove data source from run loop + * @param data_source to remove + * @returns true if data srouce was removed + */ +bool btstack_run_loop_base_remove_data_source(btstack_data_source_t * data_source); + +/** + * @brief Enable callbacks for a data source + * @param data_source to remove + * @param callback types to enable + */ +void btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); + +/** + * @brief Enable callbacks for a data source + * @param data_source to remove + * @param callback types to disable + */ +void btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); + +/** + * @brief Poll data sources. It calls the procss function for all data sources where DATA_SOURCE_CALLBACK_POLL is set + */ +void btstack_run_loop_base_poll_data_sources(void); + /* API_START */ @@ -155,6 +231,12 @@ int btstack_run_loop_remove_timer(btstack_timer_source_t * timer); */ uint32_t btstack_run_loop_get_time_ms(void); +/** + * @brief Dump timers using log_info + */ +void btstack_run_loop_timer_dump(void); + + /** * @brief Set data source callback. */ @@ -174,7 +256,6 @@ void btstack_run_loop_set_data_source_fd(btstack_data_source_t * data_source, in */ int btstack_run_loop_get_data_source_fd(btstack_data_source_t * data_source); - /** * @brief Set data source file descriptor. * @param data_source @@ -227,6 +308,8 @@ void btstack_run_loop_deinit(void); /* API_END */ + + #if defined __cplusplus } #endif diff --git a/src/btstack_run_loop_base.c b/src/btstack_run_loop_base.c index 4ebe4a0ea..74b431a71 100644 --- a/src/btstack_run_loop_base.c +++ b/src/btstack_run_loop_base.c @@ -1,140 +1,4 @@ /* - * Copyright (C) 2019 BlueKitchen GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * 4. Any redistribution, use, or modification is done solely for - * personal benefit and not for any commercial purpose or for - * monetary gain. - * - * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS - * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Please inquire about commercial licensing options at - * contact@bluekitchen-gmbh.com - * + * btstack_run_loop_base.c was integrated into btstack_run_loop.c + * Deprecated - will be removed in future releases */ - -#define BTSTACK_FILE__ "btstack_run_loop_base.c" - -/* - * btstack_run_loop_base.h - * - * Portable implementation of timer and data source management as base for platform specific implementations - */ - -#include "btstack_debug.h" -#include "btstack_config.h" -#include "btstack_util.h" - -#include "btstack_run_loop_base.h" - -// private data (access only by run loop implementations) -btstack_linked_list_t btstack_run_loop_base_timers; -btstack_linked_list_t btstack_run_loop_base_data_sources; - -void btstack_run_loop_base_init(void){ - btstack_run_loop_base_timers = NULL; - btstack_run_loop_base_data_sources = NULL; -} - -void btstack_run_loop_base_add_data_source(btstack_data_source_t *ds){ - btstack_linked_list_add(&btstack_run_loop_base_data_sources, (btstack_linked_item_t *) ds); -} - -bool btstack_run_loop_base_remove_data_source(btstack_data_source_t *ds){ - return btstack_linked_list_remove(&btstack_run_loop_base_data_sources, (btstack_linked_item_t *) ds); -} - -void btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * ds, uint16_t callback_types){ - ds->flags |= callback_types; -} - -void btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * ds, uint16_t callback_types){ - ds->flags &= ~callback_types; -} - -bool btstack_run_loop_base_remove_timer(btstack_timer_source_t *ts){ - return btstack_linked_list_remove(&btstack_run_loop_base_timers, (btstack_linked_item_t *) ts); -} - -void btstack_run_loop_base_add_timer(btstack_timer_source_t *ts){ - btstack_linked_item_t *it; - for (it = (btstack_linked_item_t *) &btstack_run_loop_base_timers; it->next ; it = it->next){ - btstack_timer_source_t * next = (btstack_timer_source_t *) it->next; - btstack_assert(next != ts); - int32_t delta = btstack_time_delta(ts->timeout, next->timeout); - if (delta < 0) break; - } - ts->item.next = it->next; - it->next = (btstack_linked_item_t *) ts; -} - -void btstack_run_loop_base_process_timers(uint32_t now){ - // process timers, exit when timeout is in the future - while (btstack_run_loop_base_timers) { - btstack_timer_source_t * ts = (btstack_timer_source_t *) btstack_run_loop_base_timers; - int32_t delta = btstack_time_delta(ts->timeout, now); - if (delta > 0) break; - btstack_run_loop_base_remove_timer(ts); - ts->process(ts); - } -} - -void btstack_run_loop_base_dump_timer(void){ -#ifdef ENABLE_LOG_INFO - btstack_linked_item_t *it; - uint16_t i = 0; - for (it = (btstack_linked_item_t *) btstack_run_loop_base_timers; it ; it = it->next){ - btstack_timer_source_t *ts = (btstack_timer_source_t*) it; - log_info("timer %u (%p): timeout %u\n", i, ts, ts->timeout); - } -#endif - -} -/** - * @brief Get time until first timer fires - * @returns -1 if no timers, time until next timeout otherwise - */ -int32_t btstack_run_loop_base_get_time_until_timeout(uint32_t now){ - if (btstack_run_loop_base_timers == NULL) return -1; - btstack_timer_source_t * ts = (btstack_timer_source_t *) btstack_run_loop_base_timers; - uint32_t list_timeout = ts->timeout; - int32_t delta = btstack_time_delta(list_timeout, now); - if (delta < 0){ - delta = 0; - } - return delta; -} - -void btstack_run_loop_base_poll_data_sources(void){ - // poll data sources - btstack_data_source_t *ds; - btstack_data_source_t *next; - for (ds = (btstack_data_source_t *) btstack_run_loop_base_data_sources; ds != NULL ; ds = next){ - next = (btstack_data_source_t *) ds->item.next; // cache pointer to next data_source to allow data source to remove itself - if (ds->flags & DATA_SOURCE_CALLBACK_POLL){ - ds->process(ds, DATA_SOURCE_CALLBACK_POLL); - } - } -} diff --git a/src/btstack_run_loop_base.h b/src/btstack_run_loop_base.h index 77aa063e9..b7ede6822 100644 --- a/src/btstack_run_loop_base.h +++ b/src/btstack_run_loop_base.h @@ -1,132 +1,4 @@ /* - * Copyright (C) 2019 BlueKitchen GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * 4. Any redistribution, use, or modification is done solely for - * personal benefit and not for any commercial purpose or for - * monetary gain. - * - * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS - * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Please inquire about commercial licensing options at - * contact@bluekitchen-gmbh.com - * + * btstack_run_loop_base.h was integrated into btstack_run_loop.h + * Deprecated - will be removed in future releases */ - -/* - * btstack_run_loop_base.h - * - * Portable implementation of timer and data source managment as base for platform specific implementations - */ - -#ifndef BTSTACK_RUN_LOOP_BASE_H -#define BTSTACK_RUN_LOOP_BASE_H - -#include "btstack_run_loop.h" - -#include "btstack_linked_list.h" - -#include - -#if defined __cplusplus -extern "C" { -#endif - -// private data (access only by run loop implementations) -extern btstack_linked_list_t btstack_run_loop_base_timers; -extern btstack_linked_list_t btstack_run_loop_base_data_sources; - -/** - * @brief Init - */ -void btstack_run_loop_base_init(void); - -/** - * @brief Add timer source. - * @param timer to add - */ -void btstack_run_loop_base_add_timer(btstack_timer_source_t * timer); - -/** - * @brief Remove timer source. - * @param timer to remove - * @returns true if timer was removed - */ -bool btstack_run_loop_base_remove_timer(btstack_timer_source_t * timer); - -/** - * @brief Process timers: remove expired timers from list and call their process function - * @param now - */ -void btstack_run_loop_base_process_timers(uint32_t now); - -/** - * @brief Dump list of timers via log_info - */ -void btstack_run_loop_base_dump_timer(void); - -/** - * @brief Get time until first timer fires - * @returns -1 if no timers, time until next timeout otherwise - */ -int32_t btstack_run_loop_base_get_time_until_timeout(uint32_t now); - -/** - * @brief Add data source to run loop - * @param data_source to add - */ -void btstack_run_loop_base_add_data_source(btstack_data_source_t * data_source); - -/** - * @brief Remove data source from run loop - * @param data_source to remove - * @returns true if data srouce was removed - */ -bool btstack_run_loop_base_remove_data_source(btstack_data_source_t * data_source); - -/** - * @brief Enable callbacks for a data source - * @param data_source to remove - * @param callback types to enable - */ -void btstack_run_loop_base_enable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); - -/** - * @brief Enable callbacks for a data source - * @param data_source to remove - * @param callback types to disable - */ -void btstack_run_loop_base_disable_data_source_callbacks(btstack_data_source_t * data_source, uint16_t callbacks); - -/** - * @brief Poll data sources. It calls the procss function for all data sources where DATA_SOURCE_CALLBACK_POLL is set - */ -void btstack_run_loop_base_poll_data_sources(void); - -#if defined __cplusplus -} -#endif - -#endif // BTSTACK_RUN_LOOP_BASE_H