diff options
Diffstat (limited to 'libril/ril_event.cpp')
-rw-r--r-- | libril/ril_event.cpp | 385 |
1 files changed, 0 insertions, 385 deletions
diff --git a/libril/ril_event.cpp b/libril/ril_event.cpp deleted file mode 100644 index 93511e9..0000000 --- a/libril/ril_event.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* //device/libs/telephony/ril_event.cpp -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "RILC" - -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <utils/Log.h> -#include <ril_event.h> -#include <string.h> -#include <sys/time.h> -#include <time.h> - -#include <pthread.h> -static pthread_mutex_t listMutex; -#define MUTEX_ACQUIRE() pthread_mutex_lock(&listMutex) -#define MUTEX_RELEASE() pthread_mutex_unlock(&listMutex) -#define MUTEX_INIT() pthread_mutex_init(&listMutex, NULL) -#define MUTEX_DESTROY() pthread_mutex_destroy(&listMutex) - -#ifndef timeradd -#define timeradd(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ - if ((vvp)->tv_usec >= 1000000) { \ - (vvp)->tv_sec++; \ - (vvp)->tv_usec -= 1000000; \ - } \ - } while (0) -#endif - -#ifndef timercmp -#define timercmp(a, b, op) \ - ((a)->tv_sec == (b)->tv_sec \ - ? (a)->tv_usec op (b)->tv_usec \ - : (a)->tv_sec op (b)->tv_sec) -#endif - -#ifndef timersub -#define timersub(a, b, res) \ - do { \ - (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((res)->tv_usec < 0) { \ - (res)->tv_usec += 1000000; \ - (res)->tv_sec -= 1; \ - } \ - } while(0); -#endif - -static fd_set readFds; -static int nfds = 0; - -static struct ril_event * watch_table[MAX_FD_EVENTS]; -static struct ril_event timer_list; -static struct ril_event pending_list; - -#define DEBUG 0 - -#if DEBUG -#define dlog(x...) ALOGD( x ) -static void dump_event(struct ril_event * ev) -{ - dlog("~~~~ Event %x ~~~~", (unsigned int)ev); - dlog(" next = %x", (unsigned int)ev->next); - dlog(" prev = %x", (unsigned int)ev->prev); - dlog(" fd = %d", ev->fd); - dlog(" pers = %d", ev->persist); - dlog(" timeout = %ds + %dus", (int)ev->timeout.tv_sec, (int)ev->timeout.tv_usec); - dlog(" func = %x", (unsigned int)ev->func); - dlog(" param = %x", (unsigned int)ev->param); - dlog("~~~~~~~~~~~~~~~~~~"); -} -#else -#define dlog(x...) do {} while(0) -#define dump_event(x) do {} while(0) -#endif - -static void getNow(struct timeval * tv) -{ -#ifdef HAVE_POSIX_CLOCKS - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - tv->tv_sec = ts.tv_sec; - tv->tv_usec = ts.tv_nsec/1000; -#else - gettimeofday(tv, NULL); -#endif -} - -static void init_list(struct ril_event * list) -{ - memset(list, 0, sizeof(struct ril_event)); - list->next = list; - list->prev = list; - list->fd = -1; -} - -static void addToList(struct ril_event * ev, struct ril_event * list) -{ - ev->next = list; - ev->prev = list->prev; - ev->prev->next = ev; - list->prev = ev; - dump_event(ev); -} - -static void removeFromList(struct ril_event * ev) -{ - dlog("~~~~ Removing event ~~~~"); - dump_event(ev); - - ev->next->prev = ev->prev; - ev->prev->next = ev->next; - ev->next = NULL; - ev->prev = NULL; -} - - -static void removeWatch(struct ril_event * ev, int index) -{ - watch_table[index] = NULL; - ev->index = -1; - - FD_CLR(ev->fd, &readFds); - - if (ev->fd+1 == nfds) { - int n = 0; - - for (int i = 0; i < MAX_FD_EVENTS; i++) { - struct ril_event * rev = watch_table[i]; - - if ((rev != NULL) && (rev->fd > n)) { - n = rev->fd; - } - } - nfds = n + 1; - dlog("~~~~ nfds = %d ~~~~", nfds); - } -} - -static void processTimeouts() -{ - dlog("~~~~ +processTimeouts ~~~~"); - MUTEX_ACQUIRE(); - struct timeval now; - struct ril_event * tev = timer_list.next; - struct ril_event * next; - - getNow(&now); - // walk list, see if now >= ev->timeout for any events - - dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); - while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) { - // Timer expired - dlog("~~~~ firing timer ~~~~"); - next = tev->next; - removeFromList(tev); - addToList(tev, &pending_list); - tev = next; - } - MUTEX_RELEASE(); - dlog("~~~~ -processTimeouts ~~~~"); -} - -static void processReadReadies(fd_set * rfds, int n) -{ - dlog("~~~~ +processReadReadies (%d) ~~~~", n); - MUTEX_ACQUIRE(); - - for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) { - struct ril_event * rev = watch_table[i]; - if (rev != NULL && FD_ISSET(rev->fd, rfds)) { - addToList(rev, &pending_list); - if (rev->persist == false) { - removeWatch(rev, i); - } - n--; - } - } - - MUTEX_RELEASE(); - dlog("~~~~ -processReadReadies (%d) ~~~~", n); -} - -static void firePending() -{ - dlog("~~~~ +firePending ~~~~"); - struct ril_event * ev = pending_list.next; - while (ev != &pending_list) { - struct ril_event * next = ev->next; - removeFromList(ev); - ev->func(ev->fd, 0, ev->param); - ev = next; - } - dlog("~~~~ -firePending ~~~~"); -} - -static int calcNextTimeout(struct timeval * tv) -{ - struct ril_event * tev = timer_list.next; - struct timeval now; - - getNow(&now); - - // Sorted list, so calc based on first node - if (tev == &timer_list) { - // no pending timers - return -1; - } - - dlog("~~~~ now = %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); - dlog("~~~~ next = %ds + %dus ~~~~", - (int)tev->timeout.tv_sec, (int)tev->timeout.tv_usec); - if (timercmp(&tev->timeout, &now, >)) { - timersub(&tev->timeout, &now, tv); - } else { - // timer already expired. - tv->tv_sec = tv->tv_usec = 0; - } - return 0; -} - -// Initialize internal data structs -void ril_event_init() -{ - MUTEX_INIT(); - - FD_ZERO(&readFds); - init_list(&timer_list); - init_list(&pending_list); - memset(watch_table, 0, sizeof(watch_table)); -} - -// Initialize an event -void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param) -{ - dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev); - memset(ev, 0, sizeof(struct ril_event)); - ev->fd = fd; - ev->index = -1; - ev->persist = persist; - ev->func = func; - ev->param = param; - fcntl(fd, F_SETFL, O_NONBLOCK); -} - -// Add event to watch list -void ril_event_add(struct ril_event * ev) -{ - dlog("~~~~ +ril_event_add ~~~~"); - MUTEX_ACQUIRE(); - for (int i = 0; i < MAX_FD_EVENTS; i++) { - if (watch_table[i] == NULL) { - watch_table[i] = ev; - ev->index = i; - dlog("~~~~ added at %d ~~~~", i); - dump_event(ev); - FD_SET(ev->fd, &readFds); - if (ev->fd >= nfds) nfds = ev->fd+1; - dlog("~~~~ nfds = %d ~~~~", nfds); - break; - } - } - MUTEX_RELEASE(); - dlog("~~~~ -ril_event_add ~~~~"); -} - -// Add timer event -void ril_timer_add(struct ril_event * ev, struct timeval * tv) -{ - dlog("~~~~ +ril_timer_add ~~~~"); - MUTEX_ACQUIRE(); - - struct ril_event * list; - if (tv != NULL) { - // add to timer list - list = timer_list.next; - ev->fd = -1; // make sure fd is invalid - - struct timeval now; - getNow(&now); - timeradd(&now, tv, &ev->timeout); - - // keep list sorted - while (timercmp(&list->timeout, &ev->timeout, < ) - && (list != &timer_list)) { - list = list->next; - } - // list now points to the first event older than ev - addToList(ev, list); - } - - MUTEX_RELEASE(); - dlog("~~~~ -ril_timer_add ~~~~"); -} - -// Remove event from watch or timer list -void ril_event_del(struct ril_event * ev) -{ - dlog("~~~~ +ril_event_del ~~~~"); - MUTEX_ACQUIRE(); - - if (ev->index < 0 || ev->index >= MAX_FD_EVENTS) { - MUTEX_RELEASE(); - return; - } - - removeWatch(ev, ev->index); - - MUTEX_RELEASE(); - dlog("~~~~ -ril_event_del ~~~~"); -} - -#if DEBUG -static void printReadies(fd_set * rfds) -{ - for (int i = 0; (i < MAX_FD_EVENTS); i++) { - struct ril_event * rev = watch_table[i]; - if (rev != NULL && FD_ISSET(rev->fd, rfds)) { - dlog("DON: fd=%d is ready", rev->fd); - } - } -} -#else -#define printReadies(rfds) do {} while(0) -#endif - -void ril_event_loop() -{ - int n; - fd_set rfds; - struct timeval tv; - struct timeval * ptv; - - - for (;;) { - - // make local copy of read fd_set - memcpy(&rfds, &readFds, sizeof(fd_set)); - if (-1 == calcNextTimeout(&tv)) { - // no pending timers; block indefinitely - dlog("~~~~ no timers; blocking indefinitely ~~~~"); - ptv = NULL; - } else { - dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec); - ptv = &tv; - } - printReadies(&rfds); - n = select(nfds, &rfds, NULL, NULL, ptv); - printReadies(&rfds); - dlog("~~~~ %d events fired ~~~~", n); - if (n < 0) { - if (errno == EINTR) continue; - - ALOGE("ril_event: select error (%d)", errno); - // bail? - return; - } - - // Check for timeouts - processTimeouts(); - // Check for read-ready - processReadReadies(&rfds, n); - // Fire away - firePending(); - } -} |