Browse Source

Use blocking queue for KeyServerLookup. Eliminated polling. Ensure KeyServerLookup thread's session is released after calling stop. Added short keyserverlookup test.

async_key_management
Edouard Tisserant 7 years ago
parent
commit
ad028884a6
4 changed files with 116 additions and 19 deletions
  1. +12
    -0
      iOSTests/iOSTests.m
  2. +6
    -1
      pEpiOSAdapter/PEPQueue.h
  3. +70
    -8
      pEpiOSAdapter/PEPQueue.m
  4. +28
    -10
      pEpiOSAdapter/PEPiOSAdapter.m

+ 12
- 0
iOSTests/iOSTests.m View File

@ -60,6 +60,18 @@ PEPSession *session;
}
- (void)testShortKeyServerLookup {
[self pEpSetUp];
[PEPiOSAdapter startKeyserverLookup];
// Do nothing.
[PEPiOSAdapter stopKeyserverLookup];
[self pEpCleanUp];
}
- (void)testTrustWords {
[self pEpSetUp];


+ 6
- 1
pEpiOSAdapter/PEPQueue.h View File

@ -8,9 +8,14 @@
#import <Foundation/Foundation.h>
@interface PEPQueue : NSMutableArray
@interface PEPQueue : NSObject
- (void)enqueue:(id)object;
- (id)dequeue;
- (void)kill;
- (NSUInteger)count;
@end

+ 70
- 8
pEpiOSAdapter/PEPQueue.m View File

@ -8,22 +8,84 @@
#import "PEPQueue.h"
@interface PEPQueue ()
@property (nonatomic, strong) NSMutableArray *queue;
@property (nonatomic, strong) NSCondition *cond;
@end
@implementation PEPQueue
- (void)enqueue:(id)object
- (id)init
{
@synchronized(self) {
[self insertObject:object atIndex:0];
self = [super init];
if (self)
{
self.queue = [[NSMutableArray alloc] init];
self.cond = [[NSCondition alloc] init];
}
return self;
}
- (void)enqueue:(id)object
{
[_cond lock];
if (_queue)
[_queue insertObject:object atIndex:0];
[_cond signal];
[_cond unlock];
}
- (id)dequeue
{
@synchronized(self) {
id object = [self lastObject];
[self removeLastObject];
return object;
id tmp = nil;
[_cond lock];
while (_queue && _queue.count == 0)
{
[_cond wait];
}
if (_queue)
{
tmp = [_queue lastObject];
[_queue removeLastObject];
}
[_cond unlock];
return tmp;
}
@end
- (void)kill
{
[_cond lock];
_queue = nil;
[_cond signal];
[_cond unlock];
}
- (NSUInteger)count
{
return [_queue count];
}
- (void)dealloc
{
self.queue = nil;
self.cond = nil;
}
@end

+ 28
- 10
pEpiOSAdapter/PEPiOSAdapter.m View File

@ -30,15 +30,14 @@ static pEp_identity *retrieve_next_identity(void *management)
{
PEPQueue *q = (__bridge PEPQueue *)management;
while (![q count])
usleep(100);
// Dequeue is a blocking operation
// that returns nil when queue is killed
NSDictionary *ident = [q dequeue];
if ([ident objectForKey:@"THE_END"])
return NULL;
else
if (ident)
return PEP_identityToStruct(ident);
else
return NULL;
}
@implementation PEPiOSAdapter
@ -97,16 +96,27 @@ static pEp_identity *retrieve_next_identity(void *management)
static PEPQueue *queue = nil;
static NSThread *keyserver_thread = nil;
static NSConditionLock *joinCond = nil;
+ (void)keyserverThread:(id)object
{
[joinCond lock];
do_keymanagement(retrieve_next_identity, (__bridge void *)queue);
// Set and signal join()
[joinCond unlockWithCondition:YES];
}
+ (void)startKeyserverLookup
{
if (!queue) {
queue = [PEPQueue init];
if (!queue)
{
queue = [[PEPQueue alloc]init];
// There is no join() call on NSThreads.
joinCond = [[NSConditionLock alloc] initWithCondition:NO];
keyserver_thread = [[NSThread alloc] initWithTarget:self selector:@selector(keyserverThread:) object:nil];
[keyserver_thread start];
}
@ -115,10 +125,18 @@ static NSThread *keyserver_thread = nil;
+ (void)stopKeyserverLookup
{
if (queue) {
[queue enqueue:[NSDictionary dictionaryWithObject:@"THE_END" forKey:@"THE_END"]];
if (queue)
{
// Flush queue and kick the consumer
[queue kill];
// Thread then bailout. Wait fo that.
[joinCond lockWhenCondition:YES];
[joinCond unlock];
keyserver_thread = nil;
queue = nil;
joinCond = nil;
}
}


Loading…
Cancel
Save