Added basic Sync' thread/queue/callback test, fixed PEPqueue that wasn't using NSCondition in a proper way, fixed possible race condition in sync thread.
authorEdouard Tisserant <edouard@pep-project.org>
Mon, 22 May 2017 13:40:33 +0200
changeset 195cbfe333e6df2
parent 194 01e62c252585
child 196 d660aae03056
Added basic Sync' thread/queue/callback test, fixed PEPqueue that wasn't using NSCondition in a proper way, fixed possible race condition in sync thread.
pEpObjCAdapter/PEPObjCAdapter.m
pEpObjCAdapter/PEPQueue.h
pEpObjCAdapter/PEPQueue.m
pEpObjCTests/iOSTests.m
     1.1 --- a/pEpObjCAdapter/PEPObjCAdapter.m	Fri May 19 10:35:35 2017 +0200
     1.2 +++ b/pEpObjCAdapter/PEPObjCAdapter.m	Mon May 22 13:40:33 2017 +0200
     1.3 @@ -305,26 +305,15 @@
     1.4  {
     1.5      [syncThreadJoinCond lock];
     1.6      
     1.7 -    PEP_STATUS status = init(&sync_session);
     1.8 -    if (status != PEP_STATUS_OK) {
     1.9 -        return;
    1.10 -    }
    1.11 -    
    1.12 -    register_sync_callbacks(sync_session,
    1.13 -                             /* "management" : queuing (unused) */
    1.14 -                            "NOTNULL",
    1.15 -                            message_to_send,
    1.16 -                            notify_handshake,
    1.17 -                            inject_sync_msg,
    1.18 -                            retrieve_next_sync_msg);
    1.19 +
    1.20 +    PEP_STATUS status;
    1.21  
    1.22      status = do_sync_protocol(sync_session,
    1.23                                /* "object" : notifying, sending (unused) */
    1.24                                "NOTNULL");
    1.25      
    1.26 -    // TODO : detach all attached sessions
    1.27 +    // TODO : log something if status not as expected
    1.28      
    1.29 -    release(sync_session);
    1.30      
    1.31      [syncThreadJoinCond unlockWithCondition:YES];
    1.32  }
    1.33 @@ -349,6 +338,19 @@
    1.34          syncQueue = [[PEPQueue alloc]init];
    1.35          
    1.36          syncThreadJoinCond = [[NSConditionLock alloc] initWithCondition:NO];
    1.37 +
    1.38 +        PEP_STATUS status = init(&sync_session);
    1.39 +        if (status != PEP_STATUS_OK) {
    1.40 +            return;
    1.41 +        }
    1.42 +        
    1.43 +        register_sync_callbacks(sync_session,
    1.44 +                                /* "management" : queuing (unused) */
    1.45 +                                "NOTNULL",
    1.46 +                                message_to_send,
    1.47 +                                notify_handshake,
    1.48 +                                inject_sync_msg,
    1.49 +                                retrieve_next_sync_msg);
    1.50          
    1.51          syncThread = [[NSThread alloc]
    1.52                        initWithTarget:self
    1.53 @@ -392,7 +394,10 @@
    1.54          
    1.55          [syncThreadJoinCond lockWhenCondition:YES];
    1.56          [syncThreadJoinCond unlock];
    1.57 +
    1.58 +        release(sync_session);
    1.59          
    1.60 +        sync_session = NULL;
    1.61          syncThread = nil;
    1.62          syncQueue = nil;
    1.63          syncThreadJoinCond = nil;
     2.1 --- a/pEpObjCAdapter/PEPQueue.h	Fri May 19 10:35:35 2017 +0200
     2.2 +++ b/pEpObjCAdapter/PEPQueue.h	Mon May 22 13:40:33 2017 +0200
     2.3 @@ -22,6 +22,4 @@
     2.4  
     2.5  - (void)purge:(deleteOp)del;
     2.6  
     2.7 -- (NSUInteger)count;
     2.8 -
     2.9  @end
     3.1 --- a/pEpObjCAdapter/PEPQueue.m	Fri May 19 10:35:35 2017 +0200
     3.2 +++ b/pEpObjCAdapter/PEPQueue.m	Mon May 22 13:40:33 2017 +0200
     3.3 @@ -33,23 +33,15 @@
     3.4  
     3.5  - (void)enqueue:(id)object
     3.6  {
     3.7 -
     3.8 -    @synchronized(self) {
     3.9 -        if (_queue)
    3.10 -            [_queue insertObject:object atIndex:0];
    3.11 -    }
    3.12 +    [_cond lock];
    3.13 +    
    3.14 +    if (_queue)
    3.15 +        [_queue insertObject:object atIndex:0];
    3.16      
    3.17      [_cond signal];
    3.18      
    3.19 -}
    3.20 -
    3.21 -- (BOOL)condwait
    3.22 -{
    3.23 -    BOOL res;
    3.24 -    @synchronized(self) {
    3.25 -        res = _queue && _queue.count == 0;
    3.26 -    }
    3.27 -    return res;
    3.28 +    [_cond unlock];
    3.29 +    
    3.30  }
    3.31  
    3.32  - (id)timedDequeue:(time_t*)timeout
    3.33 @@ -58,7 +50,7 @@
    3.34      
    3.35      [_cond lock];
    3.36      
    3.37 -    while ([self condwait])
    3.38 +    while (_queue && _queue.count == 0)
    3.39      {
    3.40          if (*timeout == 0)
    3.41          {
    3.42 @@ -79,14 +71,13 @@
    3.43          }
    3.44      }
    3.45      
    3.46 -    @synchronized(self) {
    3.47 -        if (_queue)
    3.48 -        {
    3.49 -            tmp = [_queue lastObject];
    3.50 -            
    3.51 -            [_queue removeLastObject];
    3.52 -        }
    3.53 +    if (_queue)
    3.54 +    {
    3.55 +        tmp = [_queue lastObject];
    3.56 +        
    3.57 +        [_queue removeLastObject];
    3.58      }
    3.59 +
    3.60      [_cond unlock];
    3.61      
    3.62      return tmp;
    3.63 @@ -100,35 +91,30 @@
    3.64  
    3.65  - (void)kill
    3.66  {
    3.67 -    @synchronized(self) {
    3.68 -        _queue = nil;
    3.69 -    }
    3.70 +    [_cond lock];
    3.71 +
    3.72 +    _queue = nil;
    3.73      
    3.74      [_cond signal];
    3.75 +    [_cond unlock];
    3.76 +
    3.77  }
    3.78  
    3.79  - (void)purge:(deleteOp)del
    3.80  {
    3.81 -    @synchronized(self) {
    3.82 -        id item;
    3.83 -        for (item in _queue)
    3.84 -        {
    3.85 -            del(item);
    3.86 -        }
    3.87 -        _queue = nil;
    3.88 +    [_cond lock];
    3.89 +
    3.90 +    id item;
    3.91 +    for (item in _queue)
    3.92 +    {
    3.93 +        del(item);
    3.94      }
    3.95 +    _queue = nil;
    3.96      
    3.97      [_cond signal];
    3.98 +    [_cond unlock];
    3.99  }
   3.100  
   3.101 -- (NSUInteger)count
   3.102 -{
   3.103 -    NSUInteger res;
   3.104 -    @synchronized(self) {
   3.105 -        res = [_queue count];
   3.106 -    }
   3.107 -    return res;
   3.108 -}
   3.109  
   3.110  - (void)dealloc
   3.111  {
     4.1 --- a/pEpObjCTests/iOSTests.m	Fri May 19 10:35:35 2017 +0200
     4.2 +++ b/pEpObjCTests/iOSTests.m	Mon May 22 13:40:33 2017 +0200
     4.3 @@ -11,6 +11,56 @@
     4.4  #import "PEPObjCAdapter.h"
     4.5  #import "PEPSession.h"
     4.6  
     4.7 +@interface someSyncDelegate : NSObject  <PEPSyncDelegate>
     4.8 +- (bool)waitUntilSent:(time_t)maxSec;
     4.9 +@property (nonatomic) bool sendWasCalled;
    4.10 +@property (nonatomic, strong) NSCondition *cond;
    4.11 +@end
    4.12 +
    4.13 +@implementation someSyncDelegate
    4.14 +
    4.15 +- (id)init {
    4.16 +    if (self = [super init])  {
    4.17 +        self.sendWasCalled = false;
    4.18 +        self.cond = [[NSCondition alloc] init];
    4.19 +    }
    4.20 +    return self;
    4.21 +}
    4.22 +
    4.23 +- (PEP_STATUS)notifyHandshakeWithSignal:(sync_handshake_signal)signal me:(id)me partner:(id)partner {
    4.24 +
    4.25 +    return PEP_STATUS_OK;
    4.26 +    
    4.27 +}
    4.28 +
    4.29 +- (PEP_STATUS)sendMessage:(id)msg {
    4.30 +    [_cond lock];
    4.31 +
    4.32 +    _sendWasCalled = true;
    4.33 +    [_cond signal];
    4.34 +    [_cond unlock];
    4.35 +
    4.36 +    return PEP_STATUS_OK;
    4.37 +}
    4.38 +
    4.39 +- (PEP_STATUS)fastPolling:(bool)isfast {
    4.40 +    
    4.41 +    return PEP_STATUS_OK;
    4.42 +    
    4.43 +}
    4.44 +
    4.45 +- (bool)waitUntilSent:(time_t)maxSec {
    4.46 +    bool res;
    4.47 +    [_cond lock];
    4.48 +    [_cond waitUntilDate:[NSDate dateWithTimeIntervalSinceNow: 2]];
    4.49 +    res = _sendWasCalled;
    4.50 +    [_cond unlock];
    4.51 +    return res;
    4.52 +    
    4.53 +}
    4.54 +
    4.55 +@end
    4.56 +
    4.57  @interface iOSTests : XCTestCase
    4.58  
    4.59  @end
    4.60 @@ -153,7 +203,7 @@
    4.61      [self pEpSetUp];
    4.62  
    4.63      PEPSession *session2 = [[PEPSession alloc] init];
    4.64 -    sleep(1);
    4.65 +
    4.66      session2 = nil;
    4.67  
    4.68      [self pEpCleanUp];
    4.69 @@ -195,6 +245,33 @@
    4.70      
    4.71  }
    4.72  
    4.73 +- (void)testSyncSession {
    4.74 +    
    4.75 +    someSyncDelegate *syncDelegate = [[someSyncDelegate alloc] init];
    4.76 +    [self pEpSetUp];
    4.77 +    
    4.78 +    // This should attach session just created
    4.79 +    [PEPObjCAdapter startSync:syncDelegate];
    4.80 +    
    4.81 +    
    4.82 +    NSMutableDictionary *identMe = [NSMutableDictionary dictionaryWithObjectsAndKeys:
    4.83 +                                    @"pEp Test iOS GenKey", @"username",
    4.84 +                                    @"pep.test.iosgenkey@pep-project.org", @"address",
    4.85 +                                    @"Me", @"user_id",
    4.86 +                                    nil];
    4.87 +    
    4.88 +    [session mySelf:identMe];
    4.89 +    
    4.90 +    bool res = [syncDelegate waitUntilSent:2];
    4.91 +    
    4.92 +    XCTAssert(res);
    4.93 +    
    4.94 +    // This should detach session just created
    4.95 +    [PEPObjCAdapter stopSync];
    4.96 +    
    4.97 +    [self pEpCleanUp];
    4.98 +}
    4.99 +
   4.100  - (void)testTrustWords {
   4.101      [self pEpSetUp];
   4.102