00001 #include "common/evq_timer.h" 00002 00003 #include "common/logging.h" 00004 #include "common/assertions.h" 00005 00006 #include <assert.h> 00007 #include <asm-generic/errno.h> // ETIMEDOUT 00008 #include <stdio.h> 00009 00010 // We will have the event framework make this callback when it is time to process an event. 00011 static MAYBE_ERROR_RTYPE event_cb(Event* event MAYBE_ERROR_PARAM) 00012 { 00013 Timer* timer = (Timer*)event; 00014 MAYBE_ERROR_INVOKE((*timer->callback), 0, timer->user_data); 00015 MAYBE_ERROR_RETURN; 00016 } 00017 00018 static void* worker_task(void* arg) 00019 { 00020 int error; 00021 Timer* timer = (Timer*)arg; 00022 pthread_mutex_lock(&timer->mutex); 00023 while (timer->running) { 00024 if (timer->active) { 00025 // Wait for a signal with a timer. 00026 //logt("doing timed wait"); 00027 // See asm-generic/errno.h and asm-generic/errno-base.h for the 00028 // relevant error codes. 00029 error = pthread_cond_timedwait(&timer->cond, &timer->mutex, timer->time); 00030 //logf("error is %d", error); 00031 if (timer->active) { 00032 if (error == ETIMEDOUT) { 00033 timer->active = 0; 00034 event_put(timer->queue, (Event*)timer); 00035 } else if (error) { 00036 logf("pthread_cond_timedwait error %d", error); 00037 assert(0 && "pthread_cond_timedwait invalid args?"); 00038 } 00039 } 00040 } else { 00041 // Wait for a signal without a timer. 00042 pthread_cond_wait(&timer->cond, &timer->mutex); // no error code 00043 } 00044 } 00045 pthread_mutex_unlock(&timer->mutex); 00046 return ((void*)0); 00047 } 00048 00049 void timer_init(EventQueue* queue, Timer* timer) 00050 { 00051 timer->queue = queue; 00052 timer->active = 0; 00053 timer->running = 1; 00054 timer->event.callback = &event_cb; 00055 pthread_mutex_init(&timer->mutex, NULL); 00056 pthread_cond_init(&timer->cond, NULL); 00057 pthread_create(&timer->worker, NULL, &worker_task, timer); 00058 } 00059 00060 void timer_at(Timer* timer, struct timespec* time, TimerCallback* callback, void* user_data) 00061 { 00062 pthread_mutex_lock(&timer->mutex); 00063 assert(!timer->active && "timer already active"); 00064 timer->time = time; 00065 timer->callback = callback; 00066 timer->user_data = user_data; 00067 timer->active = 1; 00068 pthread_cond_signal(&timer->cond); 00069 pthread_mutex_unlock(&timer->mutex); 00070 } 00071 00072 void timer_cancel(Timer* timer) 00073 { 00074 pthread_mutex_lock(&timer->mutex); 00075 if (timer->active) { 00076 timer->active = 0; 00077 pthread_cond_signal(&timer->cond); 00078 } else { 00079 event_remove(timer->queue, (Event*)timer); 00080 } 00081 pthread_mutex_unlock(&timer->mutex); 00082 } 00083 00084 void timer_close(Timer* timer) 00085 { 00086 timer_cancel(timer); 00087 00088 pthread_mutex_lock(&timer->mutex); 00089 timer->running = 0; 00090 pthread_cond_signal(&timer->cond); 00091 pthread_mutex_unlock(&timer->mutex); 00092 00093 void* exitValue; 00094 pthread_join(timer->worker, &exitValue); 00095 printf("timer worker exited with %d\n", (int)exitValue); 00096 00097 // Destroying these is perfectly safe now that the worker thread has stopped running. Other than the owner thread no other thread should any longer be accessing this object, and even the owner should not after calling timer_close. 00098 pthread_cond_destroy(&timer->cond); 00099 pthread_mutex_destroy(&timer->mutex); 00100 00101 // This ensures that once this call returns, the owning thread will not be processing any events relating to this timer. 00102 event_remove(timer->queue, (Event*)timer); 00103 } 00104 00105 /** 00106 00107 evq_timer.c 00108 00109 Copyright 2009 Helsinki Institute for Information Technology (HIIT) 00110 and the authors. All rights reserved. 00111 00112 Authors: Tero Hasu <tero.hasu@hut.fi> 00113 00114 Permission is hereby granted, free of charge, to any person 00115 obtaining a copy of this software and associated documentation files 00116 (the "Software"), to deal in the Software without restriction, 00117 including without limitation the rights to use, copy, modify, merge, 00118 publish, distribute, sublicense, and/or sell copies of the Software, 00119 and to permit persons to whom the Software is furnished to do so, 00120 subject to the following conditions: 00121 00122 The above copyright notice and this permission notice shall be 00123 included in all copies or substantial portions of the Software. 00124 00125 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00126 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00127 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00128 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 00129 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 00130 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00131 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00132 SOFTWARE. 00133 00134 **/
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:52 2011 by Doxygen 1.6.1