pubsub.c 2.6 KB

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