From 69364d581d959e7549d3fa1bac8a6c3184a2ed50 Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Sun, 10 Nov 2024 00:22:25 -0800
Subject: [PATCH] Extend and back-off [f]nopen() file open retries

Similar to what I do with user.tab record locks 2 months ago, this will
extend the total shared/network file open attempt duration from about 5
seconds to about 45 seconds, but with incrementing back-off.

Trying to sbbs-Linux to run from a Samba share without file open/locking
errors.

Re-synced the sbbs_t version of nopen with the nopen.c version (wasn't
special-handling EDEADLOCK failures).

Mostly we're using fnopen() these days anyway, which doesn't have an sbbs_t
version (for logging warning messages about collisions), perhaps it should.
---
 src/sbbs3/main.cpp | 6 +++---
 src/sbbs3/nopen.c  | 4 +---
 src/sbbs3/nopen.h  | 2 +-
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 52925db21b..5239672500 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -3985,14 +3985,14 @@ int sbbs_t::nopen(char *str, int access)
 	if(!(access&O_TEXT))
 		access|=O_BINARY;
     while(((file=sopen(str,access,share,DEFFILEMODE))==-1)
-        && (errno==EACCES || errno==EAGAIN) && count++<LOOP_NOPEN)
-	    mswait(100);
+        && (errno==EACCES || errno==EAGAIN || errno==EDEADLOCK) && count++<LOOP_NOPEN)
+	    SLEEP((count / 10) * 100);
     if(count>(LOOP_NOPEN/2) && count<=LOOP_NOPEN) {
         SAFEPRINTF2(logstr,"NOPEN COLLISION - File: \"%s\" Count: %d"
             ,str,count);
         logline(LOG_WARNING,"!!",logstr);
 	}
-    if(file==-1 && (errno==EACCES || errno==EAGAIN)) {
+    if(file==-1 && (errno==EACCES || errno==EAGAIN || errno==EDEADLOCK)) {
         SAFEPRINTF2(logstr,"NOPEN ACCESS DENIED - File: \"%s\" errno: %d"
 			,str,errno);
 		logline(LOG_WARNING,"!!",logstr);
diff --git a/src/sbbs3/nopen.c b/src/sbbs3/nopen.c
index 480ad9c669..e08874695b 100644
--- a/src/sbbs3/nopen.c
+++ b/src/sbbs3/nopen.c
@@ -29,7 +29,6 @@
 /* Network open function. Opens all files DENYALL, DENYWRITE, or DENYNONE	*/
 /* depending on access, and retries LOOP_NOPEN number of times if the		*/
 /* attempted file is already open or denying access  for some other reason. */
-/* All files are opened in BINARY mode.										*/
 /****************************************************************************/
 int nopen(const char* str, uint access)
 {
@@ -50,8 +49,7 @@ int nopen(const char* str, uint access)
 #endif
     while(((file=sopen(str,access,share,DEFFILEMODE))==-1)
         && (errno==EACCES || errno==EAGAIN || errno==EDEADLOCK) && count++<LOOP_NOPEN)
-        if(count)
-            SLEEP(100);
+		SLEEP((count / 10) * 100);
     return(file);
 }
 
diff --git a/src/sbbs3/nopen.h b/src/sbbs3/nopen.h
index 0df1cbf3c1..1084436cdb 100644
--- a/src/sbbs3/nopen.h
+++ b/src/sbbs3/nopen.h
@@ -27,7 +27,7 @@
 #include "gen_defs.h"		/* bool */
 
 #define FNOPEN_BUF_SIZE		(2*1024)
-#define LOOP_NOPEN	  50	/* Retries before file access denied			*/
+#define LOOP_NOPEN	  500	/* Retries before file access denied			*/
 
 #ifdef __cplusplus
 extern "C" {
-- 
GitLab