ril_event.cpp
上传用户:rftzhifu
上传日期:2017-02-21
资源大小:229k
文件大小:9k
源码类别:

android开发

开发平台:

Unix_Linux

  1. /* //device/libs/telephony/ril_event.cpp
  2. **
  3. ** Copyright 2008, The Android Open Source Project
  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. #define LOG_TAG "RILC"
  18. #include <stdlib.h>
  19. #include <unistd.h>
  20. #include <errno.h>
  21. #include <fcntl.h>
  22. #include <utils/Log.h>
  23. #include <ril_event.h>
  24. #include <string.h>
  25. #include <sys/time.h>
  26. #include <time.h>
  27. #include <pthread.h>
  28. static pthread_mutex_t listMutex;
  29. #define MUTEX_ACQUIRE() pthread_mutex_lock(&listMutex)
  30. #define MUTEX_RELEASE() pthread_mutex_unlock(&listMutex)
  31. #define MUTEX_INIT() pthread_mutex_init(&listMutex, NULL)
  32. #define MUTEX_DESTROY() pthread_mutex_destroy(&listMutex)
  33. #ifndef timeradd
  34. #define timeradd(tvp, uvp, vvp)
  35. do {
  36. (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;
  37. (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;       
  38. if ((vvp)->tv_usec >= 1000000) {
  39. (vvp)->tv_sec++;
  40. (vvp)->tv_usec -= 1000000;
  41. }
  42. } while (0)
  43. #endif
  44. #ifndef timercmp
  45. #define timercmp(a, b, op)               
  46.         ((a)->tv_sec == (b)->tv_sec      
  47.         ? (a)->tv_usec op (b)->tv_usec   
  48.         : (a)->tv_sec op (b)->tv_sec)
  49. #endif
  50. #ifndef timersub
  51. #define timersub(a, b, res)                           
  52.     do {                                              
  53.         (res)->tv_sec = (a)->tv_sec - (b)->tv_sec;    
  54.         (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; 
  55.         if ((res)->tv_usec < 0) {                     
  56.             (res)->tv_usec += 1000000;                
  57.             (res)->tv_sec -= 1;                       
  58.         }                                             
  59.     } while(0);
  60. #endif
  61. static fd_set readFds;
  62. static int nfds = 0;
  63. static struct ril_event * watch_table[MAX_FD_EVENTS];
  64. static struct ril_event timer_list;
  65. static struct ril_event pending_list;
  66. #define DEBUG 0
  67. #if DEBUG
  68. #define dlog(x...) LOGD( x )
  69. static void dump_event(struct ril_event * ev)
  70. {
  71.     dlog("~~~~ Event %x ~~~~", (unsigned int)ev);
  72.     dlog("     next    = %x", (unsigned int)ev->next);
  73.     dlog("     prev    = %x", (unsigned int)ev->prev);
  74.     dlog("     fd      = %d", ev->fd);
  75.     dlog("     pers    = %d", ev->persist);
  76.     dlog("     timeout = %ds + %dus", (int)ev->timeout.tv_sec, (int)ev->timeout.tv_usec);
  77.     dlog("     func    = %x", (unsigned int)ev->func);
  78.     dlog("     param   = %x", (unsigned int)ev->param);
  79.     dlog("~~~~~~~~~~~~~~~~~~");
  80. }
  81. #else
  82. #define dlog(x...)
  83. #define dump_event(x)
  84. #endif
  85. static void getNow(struct timeval * tv)
  86. {
  87. #ifdef HAVE_POSIX_CLOCKS
  88.     struct timespec ts;
  89.     clock_gettime(CLOCK_MONOTONIC, &ts);
  90.     tv->tv_sec = ts.tv_sec;
  91.     tv->tv_usec = ts.tv_nsec/1000;
  92. #else
  93.     gettimeofday(tv, NULL);
  94. #endif
  95. }
  96. static void init_list(struct ril_event * list)
  97. {
  98.     memset(list, 0, sizeof(struct ril_event));
  99.     list->next = list;
  100.     list->prev = list;
  101.     list->fd = -1;
  102. }
  103. static void addToList(struct ril_event * ev, struct ril_event * list)
  104. {
  105.     ev->next = list;
  106.     ev->prev = list->prev;
  107.     ev->prev->next = ev;
  108.     list->prev = ev;
  109.     dump_event(ev);
  110. }
  111. static void removeFromList(struct ril_event * ev)
  112. {
  113.     dlog("~~~~ Removing event ~~~~");
  114.     dump_event(ev);
  115.     ev->next->prev = ev->prev;
  116.     ev->prev->next = ev->next;
  117.     ev->next = NULL;
  118.     ev->prev = NULL;
  119. }
  120. static void removeWatch(struct ril_event * ev, int index)
  121. {
  122.     watch_table[index] = NULL;
  123.     ev->index = -1;
  124.     FD_CLR(ev->fd, &readFds);
  125.     if (ev->fd+1 == nfds) {
  126.         int n = 0;
  127.         for (int i = 0; i < MAX_FD_EVENTS; i++) {
  128.             struct ril_event * rev = watch_table[i];
  129.             if ((rev != NULL) && (rev->fd > n)) {
  130.                 n = rev->fd;
  131.             }
  132.         }
  133.         nfds = n + 1; 
  134.         dlog("~~~~ nfds = %d ~~~~", nfds);
  135.     }
  136. }
  137. static void processTimeouts()
  138. {
  139.     dlog("~~~~ +processTimeouts ~~~~");
  140.     MUTEX_ACQUIRE();
  141.     struct timeval now;
  142.     struct ril_event * tev = timer_list.next;
  143.     struct ril_event * next;
  144.     getNow(&now);
  145.     // walk list, see if now >= ev->timeout for any events
  146.     dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
  147.     while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) {
  148.         // Timer expired
  149.         dlog("~~~~ firing timer ~~~~");
  150.         next = tev->next;
  151.         removeFromList(tev);
  152.         addToList(tev, &pending_list);
  153.         tev = next;
  154.     }
  155.     MUTEX_RELEASE();
  156.     dlog("~~~~ -processTimeouts ~~~~");
  157. }
  158. static void processReadReadies(fd_set * rfds, int n)
  159. {
  160.     dlog("~~~~ +processReadReadies (%d) ~~~~", n);
  161.     MUTEX_ACQUIRE();
  162.     for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) {
  163.         struct ril_event * rev = watch_table[i];
  164.         if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
  165.             addToList(rev, &pending_list);
  166.             if (rev->persist == false) {
  167.                 removeWatch(rev, i);
  168.             }
  169.             n--;
  170.         }
  171.     }
  172.     MUTEX_RELEASE();
  173.     dlog("~~~~ -processReadReadies (%d) ~~~~", n);
  174. }
  175. static void firePending()
  176. {
  177.     dlog("~~~~ +firePending ~~~~");
  178.     struct ril_event * ev = pending_list.next;
  179.     while (ev != &pending_list) {
  180.         struct ril_event * next = ev->next;
  181.         removeFromList(ev);
  182.         ev->func(ev->fd, 0, ev->param); 
  183.         ev = next;
  184.     }
  185.     dlog("~~~~ -firePending ~~~~");
  186. }
  187. static int calcNextTimeout(struct timeval * tv)
  188. {
  189.     struct ril_event * tev = timer_list.next;
  190.     struct timeval now;
  191.     getNow(&now);
  192.     // Sorted list, so calc based on first node
  193.     if (tev == &timer_list) {
  194.         // no pending timers
  195.         return -1;
  196.     }
  197.     dlog("~~~~ now = %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
  198.     dlog("~~~~ next = %ds + %dus ~~~~",
  199.             (int)tev->timeout.tv_sec, (int)tev->timeout.tv_usec);
  200.     if (timercmp(&tev->timeout, &now, >)) {
  201.         timersub(&tev->timeout, &now, tv);
  202.     } else {
  203.         // timer already expired.
  204.         tv->tv_sec = tv->tv_usec = 0;
  205.     }
  206.     return 0;
  207. }
  208. // Initialize internal data structs
  209. void ril_event_init()
  210. {
  211.     MUTEX_INIT();
  212.     FD_ZERO(&readFds);
  213.     init_list(&timer_list);
  214.     init_list(&pending_list);
  215.     memset(watch_table, 0, sizeof(watch_table));
  216. }
  217. // Initialize an event
  218. void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param)
  219. {
  220.     dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev);
  221.     memset(ev, 0, sizeof(struct ril_event));
  222.     ev->fd = fd;
  223.     ev->index = -1;
  224.     ev->persist = persist;
  225.     ev->func = func;
  226.     ev->param = param;
  227.     fcntl(fd, F_SETFL, O_NONBLOCK);
  228. }
  229. // Add event to watch list
  230. void ril_event_add(struct ril_event * ev)
  231. {
  232.     dlog("~~~~ +ril_event_add ~~~~");
  233.     MUTEX_ACQUIRE();
  234.     for (int i = 0; i < MAX_FD_EVENTS; i++) {
  235.         if (watch_table[i] == NULL) {
  236.             watch_table[i] = ev;
  237.             ev->index = i;
  238.             dlog("~~~~ added at %d ~~~~", i);
  239.             dump_event(ev);
  240.             FD_SET(ev->fd, &readFds);
  241.             if (ev->fd >= nfds) nfds = ev->fd+1;
  242.             dlog("~~~~ nfds = %d ~~~~", nfds);
  243.             break;
  244.         } 
  245.     }
  246.     MUTEX_RELEASE();
  247.     dlog("~~~~ -ril_event_add ~~~~");
  248. }
  249. // Add timer event
  250. void ril_timer_add(struct ril_event * ev, struct timeval * tv)
  251. {
  252.     dlog("~~~~ +ril_timer_add ~~~~");
  253.     MUTEX_ACQUIRE();
  254.     struct ril_event * list;
  255.     if (tv != NULL) {
  256.         // add to timer list
  257.         list = timer_list.next;
  258.         ev->fd = -1; // make sure fd is invalid
  259.         struct timeval now;
  260.         getNow(&now);
  261.         timeradd(&now, tv, &ev->timeout);
  262.         // keep list sorted
  263.         while (timercmp(&list->timeout, &ev->timeout, < )
  264.                 && (list != &timer_list)) {
  265.             list = list->next;
  266.         }
  267.         // list now points to the first event older than ev
  268.         addToList(ev, list);
  269.     } 
  270.     MUTEX_RELEASE();
  271.     dlog("~~~~ -ril_timer_add ~~~~");
  272. }
  273. // Remove event from watch or timer list
  274. void ril_event_del(struct ril_event * ev)
  275. {
  276.     dlog("~~~~ +ril_event_del ~~~~");
  277.     MUTEX_ACQUIRE();
  278.     if (ev->index < 0 || ev->index >= MAX_FD_EVENTS) {
  279.         return;
  280.     }
  281.     removeWatch(ev, ev->index);
  282.     MUTEX_RELEASE();
  283.     dlog("~~~~ -ril_event_del ~~~~");
  284. }
  285. void ril_event_loop()
  286. {
  287.     int n;
  288.     fd_set rfds;
  289.     struct timeval tv;
  290.     struct timeval * ptv;
  291.     for (;;) {
  292.         // make local copy of read fd_set
  293.         memcpy(&rfds, &readFds, sizeof(fd_set));
  294.         if (-1 == calcNextTimeout(&tv)) {
  295.             // no pending timers; block indefinitely
  296.             dlog("~~~~ no timers; blocking indefinitely ~~~~");
  297.             ptv = NULL;
  298.         } else {
  299.             dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
  300.             ptv = &tv;
  301.         }
  302.         n = select(nfds, &rfds, NULL, NULL, ptv);
  303.         dlog("~~~~ %d events fired ~~~~", n);
  304.         if (n < 0) {
  305.             if (errno == EINTR) continue;
  306.             LOGE("ril_event: select error (%d)", errno);
  307.             // bail?
  308.             return;
  309.         }
  310.         // Check for timeouts
  311.         processTimeouts();
  312.         // Check for read-ready
  313.         processReadReadies(&rfds, n);
  314.         // Fire away
  315.         firePending();
  316.     }
  317. }