You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
2.4 KiB

  1. //
  2. // PEPQueue.m
  3. // pEpiOSAdapter
  4. //
  5. // Created by Volker Birk on 15.07.15.
  6. // Copyright (c) 2015 pp. All rights reserved.
  7. //
  8. #import "PEPQueue.h"
  9. @interface PEPQueue ()
  10. @property (nonatomic, strong) NSMutableArray *queue;
  11. @property (nonatomic, strong) NSCondition *cond;
  12. @end
  13. @implementation PEPQueue
  14. - (id)init
  15. {
  16. self = [super init];
  17. if (self)
  18. {
  19. self.queue = [[NSMutableArray alloc] init];
  20. self.cond = [[NSCondition alloc] init];
  21. }
  22. return self;
  23. }
  24. /// A block that gets called to modify the queue model (internal).
  25. typedef void (^queueOp)(NSMutableArray *queue);
  26. /// Lock the queue and calls the given block.
  27. /// @param block The block to invoke once the queue is locked (internal).
  28. - (void)lockQueueAndUpdateWithBlock:(queueOp)block
  29. {
  30. [_cond lock];
  31. if (_queue) {
  32. block(_queue);
  33. }
  34. [_cond signal];
  35. [_cond unlock];
  36. }
  37. - (void)enqueue:(id)object
  38. {
  39. [self lockQueueAndUpdateWithBlock:^(NSMutableArray *queue){
  40. [queue insertObject:object atIndex:0];
  41. }];
  42. }
  43. - (void)prequeue:(id)object
  44. {
  45. [self lockQueueAndUpdateWithBlock:^(NSMutableArray *queue){
  46. [queue addObject:object];
  47. }];
  48. }
  49. - (id)timedDequeue:(time_t*)timeout
  50. {
  51. id tmp = nil;
  52. [_cond lock];
  53. if (_queue && _queue.count == 0)
  54. {
  55. if (*timeout == 0)
  56. {
  57. [_cond wait];
  58. }
  59. else
  60. {
  61. NSDate *end = [NSDate dateWithTimeIntervalSinceNow: *timeout];
  62. [_cond waitUntilDate:end];
  63. NSTimeInterval remaining = [end timeIntervalSinceNow];
  64. if (remaining > 0)
  65. *timeout = remaining;
  66. else
  67. *timeout = 0;
  68. }
  69. }
  70. if (_queue)
  71. {
  72. tmp = [_queue lastObject];
  73. [_queue removeLastObject];
  74. }
  75. [_cond unlock];
  76. return tmp;
  77. }
  78. - (id)dequeue
  79. {
  80. time_t zeroTimeout = 0;
  81. return [self timedDequeue:&zeroTimeout];
  82. }
  83. - (void)kill
  84. {
  85. [_cond lock];
  86. _queue = nil;
  87. [_cond signal];
  88. [_cond unlock];
  89. }
  90. - (void)purge:(deleteOp)del
  91. {
  92. [_cond lock];
  93. id item;
  94. for (item in _queue)
  95. {
  96. del(item);
  97. }
  98. _queue = nil;
  99. [_cond signal];
  100. [_cond unlock];
  101. }
  102. - (void)removeAllObjects
  103. {
  104. [_cond lock];
  105. [self.queue removeAllObjects];
  106. [_cond signal];
  107. [_cond unlock];
  108. }
  109. - (void)dealloc
  110. {
  111. self.queue = nil;
  112. self.cond = nil;
  113. }
  114. @end