pubsub.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "pubsub.h"
  2. bool init_pubsub(PubSub* pubsub) {
  3. // mutex without name,
  4. // no attributes (unfortunatly robust mutex is not supported by FreeRTOS),
  5. // with dynamic memory allocation
  6. const osMutexAttr_t value_mutex_attr = {
  7. .name = NULL, .attr_bits = 0, .cb_mem = NULL, .cb_size = 0U};
  8. pubsub->mutex = osMutexNew(&value_mutex_attr);
  9. if(pubsub->mutex == NULL) return false;
  10. // construct list
  11. list_pubsub_cb_init(pubsub->items);
  12. return true;
  13. }
  14. bool delete_pubsub(PubSub* pubsub) {
  15. if(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK) {
  16. bool result = osMutexDelete(pubsub->mutex) == osOK;
  17. list_pubsub_cb_clear(pubsub->items);
  18. return result;
  19. } else {
  20. return false;
  21. }
  22. }
  23. PubSubItem* subscribe_pubsub(PubSub* pubsub, PubSubCallback cb, void* ctx) {
  24. if(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK) {
  25. // put uninitialized item to the list
  26. PubSubItem* item = list_pubsub_cb_push_raw(pubsub->items);
  27. // initialize item
  28. item->cb = cb;
  29. item->ctx = ctx;
  30. item->self = pubsub;
  31. // TODO unsubscribe pubsub on app exit
  32. //flapp_on_exit(unsubscribe_pubsub, item);
  33. osMutexRelease(pubsub->mutex);
  34. return item;
  35. } else {
  36. return NULL;
  37. }
  38. }
  39. bool unsubscribe_pubsub(PubSubItem* pubsub_id) {
  40. if(osMutexAcquire(pubsub_id->self->mutex, osWaitForever) == osOK) {
  41. bool result = false;
  42. // iterate over items
  43. list_pubsub_cb_it_t it;
  44. for(list_pubsub_cb_it(it, pubsub_id->self->items); !list_pubsub_cb_end_p(it);
  45. list_pubsub_cb_next(it)) {
  46. const PubSubItem* item = list_pubsub_cb_cref(it);
  47. // if the iterator is equal to our element
  48. if(item == pubsub_id) {
  49. list_pubsub_cb_remove(pubsub_id->self->items, it);
  50. result = true;
  51. break;
  52. }
  53. }
  54. osMutexRelease(pubsub_id->self->mutex);
  55. return result;
  56. } else {
  57. return false;
  58. }
  59. }
  60. bool notify_pubsub(PubSub* pubsub, void* arg) {
  61. if(osMutexAcquire(pubsub->mutex, osWaitForever) == osOK) {
  62. // iterate over subscribers
  63. list_pubsub_cb_it_t it;
  64. for(list_pubsub_cb_it(it, pubsub->items); !list_pubsub_cb_end_p(it);
  65. list_pubsub_cb_next(it)) {
  66. const PubSubItem* item = list_pubsub_cb_cref(it);
  67. item->cb(arg, item->ctx);
  68. }
  69. osMutexRelease(pubsub->mutex);
  70. return true;
  71. } else {
  72. return false;
  73. }
  74. }