1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * Copyright 2014 Couchbase, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #ifndef LCBIO_TIMER_H 19 #define LCBIO_TIMER_H 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif /** __cplusplus */ 24 25 /** 26 * @file 27 * @brief Timer Routines 28 * 29 * This file contains the timer routines. This provides a simpler interface 30 * than the one provided via the `lcb_timer_*` functions. 31 */ 32 33 /** 34 * @ingroup lcbio 35 * @defgroup lcbio-timers Timer Routines 36 * 37 * @details 38 * 39 * The timer routines here allow for an asynchronous event to be scheduled 40 * within a given amount of time, or "immediately". The basic idea is that 41 * these allow "Safe" invocation of routines without worrying about reentrancy 42 * issues. 43 * 44 * There is natually a performance hit in using these functions (since this needs 45 * to operate with the event loop) so this shouldn't be used for normal steady 46 * state operations (such as memcached operations). 47 * 48 * A timer may be created via lcbio_timer_new(). The timer's initial state 49 * is _unarmed_, meaning it will not be invoked until one of the scheduling 50 * routines are invoked. 51 * 52 * When a timer is armed, its callback (passed lcbio_timer_new()) will be 53 * invoked with the argument provided to lcbio_timer_new() as well. 54 * 55 * To schedule a timer, use the lcbio_timer_rearm() to unconditionally schedule 56 * an event within a certain timeframe, or lcbio_async_signal() to invoke the 57 * timer as soon as possible, once the event loop regains control. 58 * 59 * To cancel an armed timer (that is, to ensure the event is _not_ called), use 60 * the lcbio_timer_disarm() function or the lcbio_async_cancel() function (which 61 * itself is just an alias). 62 * 63 * Timers are not persistent, meaning that once they are fired they will enter 64 * an inactive state. 65 * 66 * @addtogroup lcbio-timers 67 * @{ 68 */ 69 70 /** @private */ 71 typedef enum { 72 LCBIO_TIMER_S_ENTERED = 0x01, 73 LCBIO_TIMER_S_DESTROYED = 0x02, 74 LCBIO_TIMER_S_ARMED = 0x04 75 } lcbio_TIMERSTATE; 76 77 /** 78 * @brief Timer callback 79 * @see lcb_timer_new() 80 */ 81 typedef void (*lcbio_TIMER_cb)(void *); 82 83 typedef struct lcbio_TIMER { 84 void *event; 85 void *data; 86 lcbio_TIMER_cb callback; 87 uint32_t usec_; 88 lcbio_TIMERSTATE state; 89 lcbio_pTABLE io; 90 } lcbio_TIMER, lcbio_ASYNC; 91 92 /** 93 * @brief Creates a new timer object. 94 * 95 * The newly created timer will be in an _unarmed_ state, but may 96 * may be activated with lcbio_timer_rearm() 97 * 98 * @param iot 99 * @param data 100 * @param callback 101 * @return A new timer object. Destroy with lcbio_timer_destroy() 102 */ 103 lcbio_TIMER * 104 lcbio_timer_new(lcbio_pTABLE iot, void *data, lcbio_TIMER_cb callback); 105 106 /** 107 * @brief Release the memory allocated by the timers 108 * @param tm the timer to free 109 */ 110 void 111 lcbio_timer_destroy(lcbio_TIMER *tm); 112 113 /** 114 * @brief Schedule the timer invocation 115 * @param timer The timer 116 * @param usec The number of microseconds (from now) in which the callback 117 * should be invoked 118 */ 119 void 120 lcbio_timer_rearm(lcbio_TIMER *timer, uint32_t usec); 121 122 /** 123 * @brief Cancel a pending invocation 124 * @param timer The timer 125 * If no pending invocation is present, this does nothing 126 */ 127 void 128 lcbio_timer_disarm(lcbio_TIMER *timer); 129 130 /** 131 * @brief Schedule an asynchronous call 132 * @param timer The timer to schedule 133 * 134 * This function is equivalent to calling 135 * @code{.c} 136 * lcbio_timer_rearm(timer, 0); 137 * @endcode 138 */ 139 void 140 lcbio_async_signal(lcbio_TIMER *timer); 141 142 /** 143 * @brief alias for lcbio_timer_disarm() 144 * @param timer 145 */ 146 void 147 lcbio_async_cancel(lcbio_TIMER *timer); 148 149 /** 150 * @brief Check if timer is armed 151 * @param timer the timer to inspect 152 * @return nonzero if armed, zero if unarmed. 153 */ 154 #define lcbio_timer_armed(timer) ((timer)->state & LCBIO_TIMER_S_ARMED) 155 156 /** 157 * Get the callback that is to be invoked for the timer 158 * @param timer the timer to query 159 * @return the current callback 160 * @see lcbio_timer_set_target() 161 */ 162 #define lcbio_timer_get_target(timer) (timer)->callback 163 164 /** 165 * Change the target callback for the timer 166 * @param timer the timer to modify 167 * @param tgt the target callback to set. 168 */ 169 #define lcbio_timer_set_target(timer, tgt) (timer)->callback = tgt 170 171 void 172 lcbio_timer_dump(lcbio_TIMER *timer, FILE *fp); 173 174 /**@}*/ 175 176 #ifdef __cplusplus 177 } 178 #endif /** __cplusplus */ 179 #endif /* LCBIO_TIMER_H */ 180