Revision: 29704
          http://sourceforge.net/p/bibdesk/svn/29704
Author:   hofman
Date:     2025-10-11 14:40:30 +0000 (Sat, 11 Oct 2025)
Log Message:
-----------
retry wwith different sharing names from async thread, retry with the same 
port, imnvalidate the port when failing to register

Modified Paths:
--------------
    trunk/bibdesk/BDSKSharingServer.m

Modified: trunk/bibdesk/BDSKSharingServer.m
===================================================================
--- trunk/bibdesk/BDSKSharingServer.m   2025-10-11 13:59:24 UTC (rev 29703)
+++ trunk/bibdesk/BDSKSharingServer.m   2025-10-11 14:40:30 UTC (rev 29704)
@@ -128,6 +128,7 @@
 @interface BDSKAsyncSharingServer : BDSKAsyncObject <NSConnectionDelegate> {
     __weak BDSKSharingServer *sharingServer;
     NSString *sharingName;
+    NSInteger tryCount;
     NSConnection *connection;
     NSMutableArray *connectedClients;
     NSMutableDictionary *registeredClients;
@@ -136,7 +137,7 @@
 }
 #pragma clang diagnostic pop
 
-- (instancetype)initWithSharingName:(NSString *)aSharingName 
forSharingServer:(BDSKSharingServer *)aSharingServer NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithSharingName:(NSString *)aSharingName 
tryCount:(NSInteger)tryCount forSharingServer:(BDSKSharingServer 
*)aSharingServer NS_DESIGNATED_INITIALIZER;
 - (instancetype)init NS_UNAVAILABLE;
 
 @property NSUInteger numberOfConnections;
@@ -336,14 +337,7 @@
 {
     BDSKASSERT(status == BDSKSharingStatusOff);
     
-    // set the (next) sharing name
-    NSString *trySharingName = nil;
-    if (tryCount == 0)
-        trySharingName = [BDSKSharingServer sharingName];
-    else
-        trySharingName = [NSString stringWithFormat:@"%@-%ld", 
[BDSKSharingServer sharingName], (long)tryCount];
-    
-    asyncServer = [[BDSKAsyncSharingServer alloc] 
initWithSharingName:trySharingName forSharingServer:self];
+    asyncServer = [[BDSKAsyncSharingServer alloc] 
initWithSharingName:[BDSKSharingServer sharingName] tryCount:tryCount 
forSharingServer:self];
     // the netService is created in the callback
     
     [self setStatus:BDSKSharingStatusStarting];
@@ -409,10 +403,12 @@
     }
 }
 
-- (void)asyncServer:(BDSKAsyncSharingServer *)aServer 
didSetupWithSharingName:(NSString *)aSharingName port:(int)port {
+- (void)asyncServer:(BDSKAsyncSharingServer *)aServer 
didSetupWithSharingName:(NSString *)aSharingName tryCount:(NSInteger)aTryCount 
port:(int)port {
     BDSKASSERT(aServer == asyncServer || asyncServer == nil);
     // the service was able to register the port
     
+    tryCount = aTryCount;
+    
     BDSKPRECONDITION(netService == nil);
     
     // lazily instantiate the NSNetService object that will advertise on our 
behalf
@@ -488,12 +484,6 @@
     asyncServer = nil;
     
     [self setStatus:BDSKSharingStatusOff];
-    
-    // try again with a different name
-    if (tryCount < MAX_TRY_COUNT) {
-        ++tryCount;
-        [self _enableSharing];
-    }
 }
 
 - (void)netServiceWillPublish:(NSNetService *)sender
@@ -513,8 +503,7 @@
     [self disableSharing];
     
     // if we have a name collision, restart with another name
-    if (err == NSNetServicesCollisionError && tryCount < MAX_TRY_COUNT) {
-        ++tryCount;
+    if (err == NSNetServicesCollisionError && ++tryCount < MAX_TRY_COUNT) {
         [self _enableSharing];
     }
     
@@ -597,12 +586,13 @@
 // If we introduce incompatible changes in future, bump this to avoid sharing 
breakage
 + (NSString *)requiredClientProtocolVersion { return @"0"; }
 
-- (instancetype)initWithSharingName:(NSString *)aSharingName 
forSharingServer:(BDSKSharingServer *)aSharingServer
+- (instancetype)initWithSharingName:(NSString *)aSharingName 
tryCount:(NSInteger)aTryCount forSharingServer:(BDSKSharingServer 
*)aSharingServer
 {
     self = [super init];
     if (self) {
         sharingServer = aSharingServer;
         sharingName = aSharingName;
+        tryCount = aTryCount;
         connectedClients = [[NSMutableArray alloc] init];
         registeredClients = [[NSMutableDictionary alloc] init];
         numberOfConnections = 0;
@@ -649,37 +639,48 @@
 - (void)didSetup
 {
     // setup our DO server that will handle requests for publications and 
passwords
-    int port = 0;
-    @try {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-        NSPort *receivePort = [NSSocketPort port];
-        if([[NSSocketPortNameServer sharedInstance] registerPort:receivePort 
name:sharingName] == NO)
-            @throw [NSString stringWithFormat:@"*** BDSKAsyncSharingServer: 
Unable to register, socket port = %p, name = '%@'", receivePort, sharingName];
-        
-        // find out what port was chosen for us
-        struct sockaddr *address = (struct sockaddr *)[[(NSSocketPort 
*)receivePort address] bytes];
-        if(address->sa_family == AF_INET)
-            port = ntohs(((struct sockaddr_in *)address)->sin_port);
-        else if(address->sa_family == AF_INET6)
-            port = ntohs(((struct sockaddr_in6 *)address)->sin6_port);
+    BOOL success = NO;
+    NSPort *receivePort = [NSSocketPort port];
+    for (; tryCount < MAX_TRY_COUNT; tryCount++) {
+        NSString *name = tryCount == 0 ? sharingName : [NSString 
stringWithFormat:@"%@-%ld", sharingName, (long)tryCount];
+        int port = 0;
+        @try {
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
+            if([[NSSocketPortNameServer sharedInstance] 
registerPort:receivePort name:name] == NO)
+                @throw [NSString stringWithFormat:@"*** 
BDSKAsyncSharingServer: Unable to register, socket port = %p, name = '%@'", 
receivePort, name];
+            
+            // find out what port was chosen for us
+            struct sockaddr *address = (struct sockaddr *)[[(NSSocketPort 
*)receivePort address] bytes];
+            if(address->sa_family == AF_INET)
+                port = ntohs(((struct sockaddr_in *)address)->sin_port);
+            else if(address->sa_family == AF_INET6)
+                port = ntohs(((struct sockaddr_in6 *)address)->sin6_port);
 
-        connection = [[NSConnection alloc] initWithReceivePort:receivePort 
sendPort:nil];
-        NSProtocolChecker *checker = [NSProtocolChecker 
protocolCheckerWithTarget:self protocol:@protocol(BDSKSharingServer)];
-        [connection setRootObject:checker];
-        
-        // so we get connection:shouldMakeNewConnection: messages
-        [connection setDelegate:self];
-#pragma clang diagnostic pop
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [sharingServer asyncServer:self 
didSetupWithSharingName:sharingName port:port];
-            // this is no longer needed
-            sharingServer = nil;
-        });
+            connection = [[NSConnection alloc] initWithReceivePort:receivePort 
sendPort:nil];
+            NSProtocolChecker *checker = [NSProtocolChecker 
protocolCheckerWithTarget:self protocol:@protocol(BDSKSharingServer)];
+            [connection setRootObject:checker];
+            
+            // so we get connection:shouldMakeNewConnection: messages
+            [connection setDelegate:self];
+    #pragma clang diagnostic pop
+            success = YES;
+            sharingName = name;
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [sharingServer asyncServer:self didSetupWithSharingName:name 
tryCount:tryCount port:port];
+                // this is no longer needed
+                sharingServer = nil;
+            });
+            break;
+        }
+        @catch(id exception) {
+            NSLog(@"%@", exception);
+        }
     }
-    @catch(id exception) {
-        NSLog(@"%@", exception);
-        // the callback from the delegate should stop the async server, and 
may try again with a different name
+    if (success == NO) {
+        // the callback from the server should stop the async server
+        sharingName = nil;
+        [receivePort invalidate];
         dispatch_async(dispatch_get_main_queue(), ^{
             [sharingServer asyncServerDidFailToSetup:self];
             // this is no longer needed
@@ -702,7 +703,8 @@
     
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    [[NSSocketPortNameServer sharedInstance] removePortForName:sharingName];
+    if (sharingName)
+        [[NSSocketPortNameServer sharedInstance] 
removePortForName:sharingName];
 #pragma clang diagnostic pop
     [[connection receivePort] invalidate];
     [connection setDelegate:nil];

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to