xref: /btstack/src/btstack_run_loop.c (revision 15d50271a243995216b0f39ccc075c6ae9fad897)
1*15d50271SMatthias Ringwald /*
2*15d50271SMatthias Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*15d50271SMatthias Ringwald  *
4*15d50271SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*15d50271SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*15d50271SMatthias Ringwald  * are met:
7*15d50271SMatthias Ringwald  *
8*15d50271SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*15d50271SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*15d50271SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*15d50271SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*15d50271SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*15d50271SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*15d50271SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*15d50271SMatthias Ringwald  *    from this software without specific prior written permission.
16*15d50271SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*15d50271SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*15d50271SMatthias Ringwald  *    monetary gain.
19*15d50271SMatthias Ringwald  *
20*15d50271SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*15d50271SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*15d50271SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*15d50271SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*15d50271SMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*15d50271SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*15d50271SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*15d50271SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*15d50271SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*15d50271SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*15d50271SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*15d50271SMatthias Ringwald  * SUCH DAMAGE.
32*15d50271SMatthias Ringwald  *
33*15d50271SMatthias Ringwald  * Please inquire about commercial licensing options at
34*15d50271SMatthias Ringwald  * [email protected]
35*15d50271SMatthias Ringwald  *
36*15d50271SMatthias Ringwald  */
37*15d50271SMatthias Ringwald 
38*15d50271SMatthias Ringwald /*
39*15d50271SMatthias Ringwald  *  run_loop.c
40*15d50271SMatthias Ringwald  *
41*15d50271SMatthias Ringwald  *  Created by Matthias Ringwald on 6/6/09.
42*15d50271SMatthias Ringwald  */
43*15d50271SMatthias Ringwald 
44*15d50271SMatthias Ringwald #include "btstack_run_loop.h"
45*15d50271SMatthias Ringwald 
46*15d50271SMatthias Ringwald #include <stdio.h>
47*15d50271SMatthias Ringwald #include <stdlib.h>  // exit()
48*15d50271SMatthias Ringwald 
49*15d50271SMatthias Ringwald 
50*15d50271SMatthias Ringwald #include "btstack_debug.h"
51*15d50271SMatthias Ringwald #include "btstack-config.h"
52*15d50271SMatthias Ringwald 
53*15d50271SMatthias Ringwald static const run_loop_t * the_run_loop = NULL;
54*15d50271SMatthias Ringwald 
55*15d50271SMatthias Ringwald extern const run_loop_t run_loop_embedded;
56*15d50271SMatthias Ringwald 
57*15d50271SMatthias Ringwald // assert run loop initialized
58*15d50271SMatthias Ringwald static void run_loop_assert(void){
59*15d50271SMatthias Ringwald     if (!the_run_loop){
60*15d50271SMatthias Ringwald         log_error("ERROR: run_loop function called before run_loop_init!");
61*15d50271SMatthias Ringwald #ifdef EMBEDDED
62*15d50271SMatthias Ringwald         exit(10);
63*15d50271SMatthias Ringwald #else
64*15d50271SMatthias Ringwald         while(1);
65*15d50271SMatthias Ringwald #endif
66*15d50271SMatthias Ringwald     }
67*15d50271SMatthias Ringwald }
68*15d50271SMatthias Ringwald 
69*15d50271SMatthias Ringwald 
70*15d50271SMatthias Ringwald void run_loop_set_timer_handler(timer_source_t *ts, void (*process)(timer_source_t *_ts)){
71*15d50271SMatthias Ringwald     ts->process = process;
72*15d50271SMatthias Ringwald };
73*15d50271SMatthias Ringwald 
74*15d50271SMatthias Ringwald void run_loop_set_data_source_handler(data_source_t *ds, int (*process)(data_source_t *_ds)){
75*15d50271SMatthias Ringwald     ds->process = process;
76*15d50271SMatthias Ringwald };
77*15d50271SMatthias Ringwald 
78*15d50271SMatthias Ringwald 
79*15d50271SMatthias Ringwald /**
80*15d50271SMatthias Ringwald  * Add data_source to run_loop
81*15d50271SMatthias Ringwald  */
82*15d50271SMatthias Ringwald void run_loop_add_data_source(data_source_t *ds){
83*15d50271SMatthias Ringwald     run_loop_assert();
84*15d50271SMatthias Ringwald     if (the_run_loop->add_data_source){
85*15d50271SMatthias Ringwald         the_run_loop->add_data_source(ds);
86*15d50271SMatthias Ringwald     } else {
87*15d50271SMatthias Ringwald         log_error("run_loop_add_data_source not implemented");
88*15d50271SMatthias Ringwald     }
89*15d50271SMatthias Ringwald }
90*15d50271SMatthias Ringwald 
91*15d50271SMatthias Ringwald /**
92*15d50271SMatthias Ringwald  * Remove data_source from run loop
93*15d50271SMatthias Ringwald  */
94*15d50271SMatthias Ringwald int run_loop_remove_data_source(data_source_t *ds){
95*15d50271SMatthias Ringwald     run_loop_assert();
96*15d50271SMatthias Ringwald     if (the_run_loop->remove_data_source){
97*15d50271SMatthias Ringwald         return the_run_loop->remove_data_source(ds);
98*15d50271SMatthias Ringwald     } else {
99*15d50271SMatthias Ringwald         log_error("run_loop_remove_data_source not implemented");
100*15d50271SMatthias Ringwald         return 0;
101*15d50271SMatthias Ringwald     }
102*15d50271SMatthias Ringwald }
103*15d50271SMatthias Ringwald 
104*15d50271SMatthias Ringwald void run_loop_set_timer(timer_source_t *a, uint32_t timeout_in_ms){
105*15d50271SMatthias Ringwald     run_loop_assert();
106*15d50271SMatthias Ringwald     the_run_loop->set_timer(a, timeout_in_ms);
107*15d50271SMatthias Ringwald }
108*15d50271SMatthias Ringwald 
109*15d50271SMatthias Ringwald /**
110*15d50271SMatthias Ringwald  * Add timer to run_loop (keep list sorted)
111*15d50271SMatthias Ringwald  */
112*15d50271SMatthias Ringwald void run_loop_add_timer(timer_source_t *ts){
113*15d50271SMatthias Ringwald     run_loop_assert();
114*15d50271SMatthias Ringwald     the_run_loop->add_timer(ts);
115*15d50271SMatthias Ringwald }
116*15d50271SMatthias Ringwald 
117*15d50271SMatthias Ringwald /**
118*15d50271SMatthias Ringwald  * Remove timer from run loop
119*15d50271SMatthias Ringwald  */
120*15d50271SMatthias Ringwald int run_loop_remove_timer(timer_source_t *ts){
121*15d50271SMatthias Ringwald     run_loop_assert();
122*15d50271SMatthias Ringwald     return the_run_loop->remove_timer(ts);
123*15d50271SMatthias Ringwald }
124*15d50271SMatthias Ringwald 
125*15d50271SMatthias Ringwald /**
126*15d50271SMatthias Ringwald  * @brief Get current time in ms
127*15d50271SMatthias Ringwald  */
128*15d50271SMatthias Ringwald uint32_t run_loop_get_time_ms(void){
129*15d50271SMatthias Ringwald     run_loop_assert();
130*15d50271SMatthias Ringwald     return the_run_loop->get_time_ms();
131*15d50271SMatthias Ringwald }
132*15d50271SMatthias Ringwald 
133*15d50271SMatthias Ringwald 
134*15d50271SMatthias Ringwald void run_loop_timer_dump(void){
135*15d50271SMatthias Ringwald     run_loop_assert();
136*15d50271SMatthias Ringwald     the_run_loop->dump_timer();
137*15d50271SMatthias Ringwald }
138*15d50271SMatthias Ringwald 
139*15d50271SMatthias Ringwald /**
140*15d50271SMatthias Ringwald  * Execute run_loop
141*15d50271SMatthias Ringwald  */
142*15d50271SMatthias Ringwald void run_loop_execute(void){
143*15d50271SMatthias Ringwald     run_loop_assert();
144*15d50271SMatthias Ringwald     the_run_loop->execute();
145*15d50271SMatthias Ringwald }
146*15d50271SMatthias Ringwald 
147*15d50271SMatthias Ringwald // init must be called before any other run_loop call
148*15d50271SMatthias Ringwald void run_loop_init(const run_loop_t * run_loop){
149*15d50271SMatthias Ringwald     if (the_run_loop){
150*15d50271SMatthias Ringwald         log_error("ERROR: run loop initialized twice!");
151*15d50271SMatthias Ringwald #ifdef EMBEDDED
152*15d50271SMatthias Ringwald         while(1);
153*15d50271SMatthias Ringwald #else
154*15d50271SMatthias Ringwald         exit(10);
155*15d50271SMatthias Ringwald #endif
156*15d50271SMatthias Ringwald     }
157*15d50271SMatthias Ringwald     the_run_loop = run_loop;
158*15d50271SMatthias Ringwald     the_run_loop->init();
159*15d50271SMatthias Ringwald }
160*15d50271SMatthias Ringwald 
161