1/* 2 * Copyright (c) 2000-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * Timer.c 26 * - hides the details of how to get a timer callback 27 * - wraps the CFRunLoopTimer functionality 28 */ 29 30/* 31 * Modification History 32 * 33 * October 26, 2001 Dieter Siegmund (dieter@apple.com) 34 * - created (based on bootp/IPConfiguration.tproj/timer.c) 35 */ 36 37#include <stdlib.h> 38#include <unistd.h> 39#include <string.h> 40#include <stdio.h> 41#include <sys/types.h> 42#include <math.h> 43#include <CoreFoundation/CFRunLoop.h> 44#include "Timer.h" 45#include "myCFUtil.h" 46#include "mylog.h" 47 48 49struct Timer_s { 50 Timer_func_t * func; 51 void * arg1; 52 void * arg2; 53 void * arg3; 54 void * rls; 55 bool enabled; 56}; 57 58 59#define USECS_PER_SEC (1000 * 1000) 60 61/** 62 ** Timer timer functions 63 **/ 64 65static void 66Timer_process(CFRunLoopTimerRef rls, void * info) 67{ 68 TimerRef timer = (TimerRef)info; 69 70 if (timer->func && timer->enabled) { 71 timer->enabled = 0; 72 (*timer->func)(timer->arg1, timer->arg2, timer->arg3); 73 } 74 return; 75} 76 77TimerRef 78Timer_create() 79{ 80 TimerRef timer; 81 82 timer = malloc(sizeof(*timer)); 83 if (timer == NULL) 84 return (NULL); 85 bzero(timer, sizeof(*timer)); 86 return (timer); 87} 88 89void 90Timer_free(TimerRef * timer_p) 91{ 92 TimerRef timer = *timer_p; 93 94 if (timer == NULL) 95 return; 96 97 Timer_cancel(timer); 98 free(timer); 99 *timer_p = NULL; 100 return; 101} 102 103int 104Timer_set_relative(TimerRef timer, 105 struct timeval rel_time, Timer_func_t * func, 106 void * arg1, void * arg2, void * arg3) 107{ 108 CFRunLoopTimerContext context = { 0, NULL, NULL, NULL, NULL }; 109 CFAbsoluteTime wakeup_time; 110 111 if (timer == NULL) { 112 return (0); 113 } 114 Timer_cancel(timer); 115 timer->enabled = 0; 116 if (func == NULL) { 117 return (0); 118 } 119 timer->func = func; 120 timer->arg1 = arg1; 121 timer->arg2 = arg2; 122 timer->arg3 = arg3; 123 timer->enabled = 1; 124 if (rel_time.tv_sec <= 0 && rel_time.tv_usec < 1000) { 125 rel_time.tv_sec = 0; 126 rel_time.tv_usec = 1000; /* force millisecond resolution */ 127 } 128 wakeup_time = CFAbsoluteTimeGetCurrent() + rel_time.tv_sec 129 + ((double)rel_time.tv_usec / USECS_PER_SEC); 130 context.info = timer; 131 timer->rls 132 = CFRunLoopTimerCreate(NULL, wakeup_time, 133 0.0, 0, 0, 134 Timer_process, 135 &context); 136 CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer->rls, 137 kCFRunLoopDefaultMode); 138 return (1); 139} 140 141void 142Timer_cancel(TimerRef timer) 143{ 144 if (timer == NULL) { 145 return; 146 } 147 timer->enabled = 0; 148 timer->func = NULL; 149 if (timer->rls) { 150 CFRunLoopTimerInvalidate(timer->rls); 151 my_CFRelease(&timer->rls); 152 } 153 return; 154} 155 156/** 157 ** timer functions 158 **/ 159long 160Timer_current_secs() 161{ 162 return ((long)CFAbsoluteTimeGetCurrent()); 163} 164 165struct timeval 166Timer_current_time() 167{ 168 double t = CFAbsoluteTimeGetCurrent(); 169 struct timeval tv; 170 171 tv.tv_sec = (int32_t)t; 172 tv.tv_usec = (t - tv.tv_sec) * USECS_PER_SEC; 173 174 return (tv); 175} 176