You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
2.4 KiB
Objective-C
154 lines
2.4 KiB
Objective-C
//
|
|
// PEPQueue.m
|
|
// pEpiOSAdapter
|
|
//
|
|
// Created by Volker Birk on 15.07.15.
|
|
// Copyright (c) 2015 p≡p. All rights reserved.
|
|
//
|
|
|
|
#import "PEPQueue.h"
|
|
|
|
|
|
@interface PEPQueue ()
|
|
|
|
@property (nonatomic, strong) NSMutableArray *queue;
|
|
@property (nonatomic, strong) NSCondition *cond;
|
|
|
|
@end
|
|
|
|
@implementation PEPQueue
|
|
|
|
- (id)init
|
|
{
|
|
self = [super init];
|
|
|
|
if (self)
|
|
{
|
|
self.queue = [[NSMutableArray alloc] init];
|
|
self.cond = [[NSCondition alloc] init];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
/// A block that gets called to modify the queue model (internal).
|
|
typedef void (^queueOp)(NSMutableArray *queue);
|
|
|
|
/// Lock the queue and calls the given block.
|
|
/// @param block The block to invoke once the queue is locked (internal).
|
|
- (void)lockQueueAndUpdateWithBlock:(queueOp)block
|
|
{
|
|
[_cond lock];
|
|
|
|
if (_queue) {
|
|
block(_queue);
|
|
}
|
|
|
|
[_cond signal];
|
|
[_cond unlock];
|
|
}
|
|
|
|
- (void)enqueue:(id)object
|
|
{
|
|
[self lockQueueAndUpdateWithBlock:^(NSMutableArray *queue){
|
|
[queue insertObject:object atIndex:0];
|
|
}];
|
|
}
|
|
|
|
- (void)prequeue:(id)object
|
|
{
|
|
[self lockQueueAndUpdateWithBlock:^(NSMutableArray *queue){
|
|
[queue addObject:object];
|
|
}];
|
|
}
|
|
|
|
- (id)timedDequeue:(time_t*)timeout
|
|
{
|
|
id tmp = nil;
|
|
|
|
[_cond lock];
|
|
|
|
if (_queue && _queue.count == 0)
|
|
{
|
|
if (*timeout == 0)
|
|
{
|
|
[_cond wait];
|
|
}
|
|
else
|
|
{
|
|
NSDate *end = [NSDate dateWithTimeIntervalSinceNow: *timeout];
|
|
|
|
[_cond waitUntilDate:end];
|
|
|
|
NSTimeInterval remaining = [end timeIntervalSinceNow];
|
|
|
|
if (remaining > 0)
|
|
*timeout = remaining;
|
|
else
|
|
*timeout = 0;
|
|
}
|
|
}
|
|
|
|
if (_queue)
|
|
{
|
|
tmp = [_queue lastObject];
|
|
|
|
[_queue removeLastObject];
|
|
}
|
|
|
|
[_cond unlock];
|
|
|
|
return tmp;
|
|
}
|
|
|
|
- (id)dequeue
|
|
{
|
|
time_t zeroTimeout = 0;
|
|
return [self timedDequeue:&zeroTimeout];
|
|
}
|
|
|
|
- (void)kill
|
|
{
|
|
[_cond lock];
|
|
|
|
_queue = nil;
|
|
|
|
[_cond signal];
|
|
[_cond unlock];
|
|
|
|
}
|
|
|
|
- (void)purge:(deleteOp)del
|
|
{
|
|
[_cond lock];
|
|
|
|
id item;
|
|
for (item in _queue)
|
|
{
|
|
del(item);
|
|
}
|
|
_queue = nil;
|
|
|
|
[_cond signal];
|
|
[_cond unlock];
|
|
}
|
|
|
|
- (void)removeAllObjects
|
|
{
|
|
[_cond lock];
|
|
|
|
[self.queue removeAllObjects];
|
|
|
|
[_cond signal];
|
|
[_cond unlock];
|
|
}
|
|
|
|
|
|
- (void)dealloc
|
|
{
|
|
self.queue = nil;
|
|
self.cond = nil;
|
|
}
|
|
|
|
@end
|