queue.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * libZRTP SDK library, implements the ZRTP secure VoIP protocol.
  3. * Copyright (c) 2006-2009 Philip R. Zimmermann. All rights reserved.
  4. * Contact: http://philzimmermann.com
  5. * For licensing and other legal details, see the file zrtp_legal.c.
  6. *
  7. * Viktor Krykun <v.krikun at zfoneproject.com>
  8. */
  9. #include "zrtp.h"
  10. #include "queue.h"
  11. struct zrtp_queue {
  12. zrtp_sem_t* size_sem;
  13. zrtp_sem_t* main_sem;
  14. zrtp_mutex_t* mutex;
  15. mlist_t head;
  16. uint32_t size;
  17. };
  18. zrtp_status_t zrtp_test_queue_create(zrtp_queue_t** queue) {
  19. zrtp_status_t s = zrtp_status_fail;
  20. zrtp_queue_t* new_queue = (zrtp_queue_t*) zrtp_sys_alloc(sizeof(zrtp_queue_t));
  21. if (! new_queue) {
  22. return zrtp_status_fail;
  23. }
  24. zrtp_memset(new_queue, 0, sizeof(zrtp_queue_t));
  25. do {
  26. s = zrtp_sem_init(&new_queue->size_sem, ZRTP_QUEUE_SIZE, ZRTP_QUEUE_SIZE);
  27. if (zrtp_status_ok != s) {
  28. break;
  29. }
  30. s = zrtp_sem_init(&new_queue->main_sem, 0, ZRTP_QUEUE_SIZE);
  31. if (zrtp_status_ok != s) {
  32. break;
  33. }
  34. s = zrtp_mutex_init(&new_queue->mutex);
  35. if (zrtp_status_ok != s) {
  36. break;
  37. }
  38. init_mlist(&new_queue->head);
  39. new_queue->size = 0;
  40. s = zrtp_status_ok;
  41. } while (0);
  42. if (zrtp_status_ok != s) {
  43. if (new_queue->size_sem) {
  44. zrtp_sem_destroy(new_queue->size_sem);
  45. }
  46. if (new_queue->main_sem) {
  47. zrtp_sem_destroy(new_queue->main_sem);
  48. }
  49. if (new_queue->mutex) {
  50. zrtp_mutex_destroy(new_queue->mutex);
  51. }
  52. }
  53. *queue = new_queue;
  54. return s;
  55. }
  56. void zrtp_test_queue_destroy(zrtp_queue_t* queue) {
  57. if (queue->size_sem) {
  58. zrtp_sem_destroy(queue->size_sem);
  59. }
  60. if (queue->main_sem) {
  61. zrtp_sem_destroy(queue->main_sem);
  62. }
  63. if (queue->mutex) {
  64. zrtp_mutex_destroy(queue->mutex);
  65. }
  66. }
  67. void zrtp_test_queue_push(zrtp_queue_t* queue, zrtp_queue_elem_t* elem) {
  68. zrtp_sem_wait(queue->size_sem);
  69. zrtp_mutex_lock(queue->mutex);
  70. mlist_add_tail(&queue->head, &elem->_mlist);
  71. queue->size++;
  72. zrtp_mutex_unlock(queue->mutex);
  73. zrtp_sem_post(queue->main_sem);
  74. }
  75. zrtp_queue_elem_t* zrtp_test_queue_pop(zrtp_queue_t* queue) {
  76. zrtp_queue_elem_t* res = NULL;
  77. zrtp_sem_wait(queue->main_sem);
  78. zrtp_mutex_lock(queue->mutex);
  79. if (queue->size) {
  80. zrtp_queue_elem_t* elem_cover = mlist_get_struct(zrtp_queue_elem_t, _mlist, queue->head.next);
  81. res = elem_cover;
  82. mlist_del(queue->head.next);
  83. queue->size--;
  84. zrtp_sem_post(queue->size_sem);
  85. } else {
  86. zrtp_sem_post(queue->main_sem);
  87. }
  88. zrtp_mutex_unlock(queue->mutex);
  89. return res;
  90. }