pEpObjCAdapter/PEPSync.m
author Dirk Zimmermann <dirk@pep-project.org>
Tue, 30 Oct 2018 14:50:53 +0100
branchIOSAD-103
changeset 727 ee1a48769933
parent 726 7ebac3f25160
child 728 dbdd2b289a10
permissions -rw-r--r--
IOSAD-103 sync thread loop skeleton
     1 //
     2 //  PEPSync.m
     3 //  pEpObjCAdapter
     4 //
     5 //  Created by Dirk Zimmermann on 04.10.18.
     6 //  Copyright © 2018 p≡p. All rights reserved.
     7 //
     8 
     9 #import "PEPSync.h"
    10 
    11 #import "PEPSyncSendMessageDelegate.h"
    12 #import "PEPNotifyHandshakeDelegate.h"
    13 #import "PEPMessageUtil.h"
    14 #import "PEPMessage.h"
    15 #import "PEPQueue.h"
    16 #import "PEPLock.h"
    17 #import "PEPObjCAdapter.h"
    18 #import "NSError+PEP.h"
    19 
    20 // MARK: - Declare internals
    21 
    22 typedef PEP_STATUS (* t_messageToSendCallback)(struct _message *msg);
    23 typedef int (* t_injectSyncCallback)(SYNC_EVENT ev, void *management);
    24 
    25 @interface PEPSync ()
    26 
    27 + (PEPSync * _Nullable)instance;
    28 
    29 @property (nonatomic, nullable, weak) id<PEPSyncSendMessageDelegate> syncSendMessageDelegate;
    30 @property (nonatomic, nullable, weak) id<PEPNotifyHandshakeDelegate> notifyHandshakeDelegate;
    31 @property (nonatomic, nonnull) PEPQueue *queue;
    32 @property (nonatomic, nullable) NSThread *syncThread;
    33 
    34 /**
    35  @Return: The callback for message sending that should be used on every session init.
    36  */
    37 + (t_messageToSendCallback)messageToSendCallback;
    38 
    39 /**
    40  @Return: The callback for injectiong sync messages that should be used on every session init.
    41  */
    42 + (t_injectSyncCallback)injectSyncCallback;
    43 
    44 - (int)injectSyncEvent:(SYNC_EVENT)event;
    45 - (SYNC_EVENT)retrieveNextSyncEvent:(time_t)threshold;
    46 
    47 @end
    48 
    49 // MARK: - Callbacks called by the engine, used in session init and register_sync_callbacks
    50 
    51 static PEP_STATUS messageToSendObjc(struct _message *msg)
    52 {
    53     id<PEPSyncSendMessageDelegate> delegate = [[PEPSync instance] syncSendMessageDelegate];
    54     if (delegate) {
    55         PEPMessage *theMessage = pEpMessageFromStruct(msg);
    56         return [delegate sendMessage:theMessage];
    57     } else {
    58         return PEP_SYNC_NO_MESSAGE_SEND_CALLBACK;
    59     }
    60 }
    61 
    62 static int inject_sync_eventObjc(SYNC_EVENT ev, void *management)
    63 {
    64     PEPSync *pEpSync = [PEPSync instance];
    65 
    66     if (!pEpSync) {
    67         pEpSync = (PEPSync *) CFBridgingRelease(management);
    68     }
    69 
    70     if (pEpSync) {
    71         return [pEpSync injectSyncEvent:ev];
    72     } else {
    73         return 1;
    74     }
    75 }
    76 
    77 static SYNC_EVENT retrieve_next_sync_event(void *management, time_t threshold)
    78 {
    79     PEPSync *sync = (PEPSync *) CFBridgingRelease(management);
    80     return [sync retrieveNextSyncEvent:threshold];
    81 }
    82 
    83 // MARK: - Internal globals
    84 
    85 static __weak PEPSync *s_pEpSync;
    86 
    87 // MARK: - Public PEPSync class
    88 
    89 @implementation PEPSync
    90 
    91 + (t_messageToSendCallback)messageToSendCallback
    92 {
    93     return messageToSendObjc;
    94 }
    95 
    96 + (t_injectSyncCallback)injectSyncCallback
    97 {
    98     return inject_sync_eventObjc;
    99 }
   100 
   101 + (PEP_SESSION)createSession:(NSError **)error
   102 {
   103     [PEPSync setupTrustWordsDB];
   104 
   105     PEP_SESSION session = NULL;
   106 
   107     [PEPLock lockWrite];
   108     PEP_STATUS status = init(&session,
   109                              [PEPSync messageToSendCallback],
   110                              [PEPSync injectSyncCallback]);
   111     [PEPLock unlockWrite];
   112 
   113     if (status != PEP_STATUS_OK) {
   114         if (error) {
   115             *error = [NSError errorWithPEPStatus:status];
   116         }
   117         return nil;
   118     }
   119 
   120     return session;
   121 }
   122 
   123 + (void)releaseSession:(PEP_SESSION)session
   124 {
   125     [PEPLock lockWrite];
   126     release(session);
   127     [PEPLock unlockWrite];
   128 }
   129 
   130 - (instancetype)initWithSyncSendMessageDelegate:(id<PEPSyncSendMessageDelegate>
   131                                                  _Nonnull)syncSendMessageDelegate
   132                         notifyHandshakeDelegate:(id<PEPNotifyHandshakeDelegate>
   133                                                  _Nonnull)notifyHandshakeDelegate
   134 {
   135     if (self = [super init]) {
   136         _syncSendMessageDelegate = syncSendMessageDelegate;
   137         _notifyHandshakeDelegate = notifyHandshakeDelegate;
   138         _queue = [PEPQueue new];
   139         s_pEpSync = self;
   140     }
   141     return self;
   142 }
   143 
   144 - (void)startup
   145 {
   146     NSThread *theSyncThread = [[NSThread alloc] initWithTarget:self
   147                                                       selector:@selector(syncThreadLoop:)
   148                                                         object:nil];
   149     self.syncThread = theSyncThread;
   150 }
   151 
   152 - (void)shutdown
   153 {
   154 }
   155 
   156 // MARK: - Private
   157 
   158 + (PEPSync * _Nullable)instance
   159 {
   160     return s_pEpSync;
   161 }
   162 
   163 + (void)setupTrustWordsDB
   164 {
   165     static dispatch_once_t once;
   166     dispatch_once(&once, ^{
   167         [PEPObjCAdapter setupTrustWordsDB:[NSBundle bundleForClass:[self class]]];
   168     });
   169 }
   170 
   171 - (void)syncThreadLoop:(id)object {
   172     NSError *error = nil;
   173     PEP_SESSION session = [PEPSync createSession:&error];
   174 
   175     if (session) {
   176     } else {
   177     }
   178 
   179     [PEPSync releaseSession:session];
   180 }
   181 
   182 - (int)injectSyncEvent:(SYNC_EVENT)event
   183 {
   184     [self.queue enqueue:[NSValue valueWithBytes:&event objCType:@encode(SYNC_EVENT)]];
   185     return 0;
   186 }
   187 
   188 - (SYNC_EVENT)retrieveNextSyncEvent:(time_t)threshold
   189 {
   190     NSValue *value = [self.queue timedDequeue:&threshold];
   191     if (value) {
   192         SYNC_EVENT event;
   193         [value getValue:&event];
   194         return event;
   195     } else {
   196         return new_sync_timeout_event();
   197     }
   198 }
   199 
   200 @end