Simple HTTP Server crashes on linux/mac on stress test

Just starting out? Need help? Post your questions and find answers here.
User avatar
skinkairewalker
Addict
Addict
Posts: 824
Joined: Fri Dec 04, 2015 9:26 pm

Re: Simple HTTP Server crashes on linux/mac on stress test

Post by skinkairewalker »

Hello everyone, happy New Year! Many blessings for this year…
infratec wrote: Wed Dec 31, 2025 2:58 pm I tested it on linux and added some stuff to avoid endless loops and segmentation faults cause of not correct connections.
The server works in my environment.
I ran a test on macOS M2 with Tahoe 26.1 and PB 6.30 beta 6. The Mac is apparently causing something wrong with the WebView gadget , it’s not loading the page completely.
I’m testing it with SpiderBasic code (I tested both simple and complex code). It doesn’t load on the first try, I have to reload several times for the page to appear.
However, it works normally in both Chrome and Safari, they load on the first try. In the WebView gadget, I have to keep reloading the page until it loads correctly.

debug output (webview gadget loading):

Code: Select all

HTTP IPv6 on port 8080
HTTPS IPv4 on port 8443
HTTPS IPv6 on port 8443
HTTP IPv4 on port 8080
Was not able to start server 8080
Was not able to start server 8443
Connect 33940914392
Data 33940914392
ClientThread 33940914392
/Users/waldemarlima/Downloads/new/www/index.html 1812 33940914392
Connect 33970785544
Connect 33970787176
Connect 33970785880
Connect 33970786264
Connect 33970786216
Connect 33970786024
Data 33970786024
Data 33970786216
Data 33970786264
ClientThread 33970786216
Data 33970785880
Data 33970787176
Data 33970785544
/Users/waldemarlima/Downloads/new/www/dependencies/main.js 2564 33970786216
Delete 33940914392 by disconnect
ClientThread 33970786264
/Users/waldemarlima/Downloads/new/www/dependencies/debug.js 6488 33970786264
ClientThread 33970786024
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/themes/flat/flat.css 146173 33970786024
ClientThread 33970785880
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/dojo.js 598521 33970785880
ClientThread 33970787176
/Users/waldemarlima/Downloads/new/www/dependencies/init.js 2481 33970787176
ClientThread 33970785544
/Users/waldemarlima/Downloads/new/www/dependencies/platform.js 37198 33970785544
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed 8336 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed 8264 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed 8192 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
SendNetworkData failed -1 33970785880
Connect 33970787416
Connect 33970787320
Connect 33970785496
Connect 33970785976
Data 33970785976
Data 33970785496
Data 33970787320
Data 33970787416
ClientThread 33970785496
ClientThread 33970787320
Delete 33970786024 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/xdate.min.js 7244 33970787320
ClientThread 33970785976
Delete 33970786216 by disconnect
/Users/waldemarlima/Downloads/new/www/core.js 163471 33970785976
Delete 33970786264 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/themes/flat/window.css 2949 33970785496
Delete 33970787176 by disconnect
Delete 33970785544 by disconnect
ClientThread 33970787416
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/dgrid/css/dgrid.css 5994 33970787416
Connect 33970786024
Data 33970786024
Delete 33970785976 by disconnect
ClientThread 33970786024
Delete 33970785496 by disconnect
Delete 33970787320 by disconnect
Delete 33970787416 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/media/background.png 215514 33970786024
Delete 33970786024 by disconnect

debug output (chrome loading):

Code: Select all

Connect 36512448776
Connect 36512450984
Data 36512448776
ClientThread 36512448776
/Users/waldemarlima/Downloads/new/www/index.html 1812 36512448776
Connect 36512451032
Connect 36512451080
Connect 36512448680
Connect 36512448632
Connect 36512448728
Data 36512448728
Data 36512448632
ClientThread 36512448728
Data 36512448680
ClientThread 36512448632
Data 36512451080
ClientThread 36512448680
Data 36512451032
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/dgrid/css/dgrid.css 5994 36512448728
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/themes/flat/flat.css 146173 36512448632
ClientThread 36512451080
/Users/waldemarlima/Downloads/new/www/dependencies/debug.js 6488 36512448680
Data 36512450984
ClientThread 36512451032
/Users/waldemarlima/Downloads/new/www/dependencies/init.js 2481 36512451032
Delete 36512448776 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/dojo.js 598521 36512451080
ClientThread 36512450984
/Users/waldemarlima/Downloads/new/www/dependencies/platform.js 37198 36512450984
Connect 36512448776
Connect 36512448824
Connect 36512448584
Connect 36512450936
Data 36512450936
Data 36512448584
ClientThread 36512450936
Data 36512448824
ClientThread 36512448584
Data 36512448776
ClientThread 36512448824
/Users/waldemarlima/Downloads/new/www/core.js 163471 36512450936
/Users/waldemarlima/Downloads/new/www/dependencies/xdate.min.js 7244 36512448584
ClientThread 36512448776
/Users/waldemarlima/Downloads/new/www/dependencies/themes/flat/window.css 2949 36512448776
/Users/waldemarlima/Downloads/new/www/dependencies/main.js 2564 36512448824
Delete 36512448728 by disconnect
Delete 36512448632 by disconnect
Delete 36512448680 by disconnect
Delete 36512451080 by disconnect
Delete 36512451032 by disconnect
Delete 36512450984 by disconnect
Connect 36512450984
Connect 36512451032
Connect 36512451080
Data 36512451080
Data 36512451032
ClientThread 36512451080
Data 36512450984
ClientThread 36512451032
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/cbtree/errors/CBTErrors.json 1560 36512451080
/Users/waldemarlima/Downloads/new/www/dependencies/put.min.js 2011 36512451032
ClientThread 36512450984
Connect 36512448680
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/nls/dojo_pt-br.js 7447 36512450984
Connect 36512448632
Connect 36512448728
Data 36512448728
Data 36512448632
Data 36512448680
ClientThread 36512448728
ClientThread 36512448632
/Users/waldemarlima/Downloads/new/www/dependencies/canvas-toBlob.min.js 1297 36512448728
ClientThread 36512448680
Delete 36512450936 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/filesaver.min.js 3159 36512448632
/Users/waldemarlima/Downloads/new/www/dependencies/jquery.min.js 88145 36512448680
Connect 36514078520
Data 36514078520
Delete 36512451080 by disconnect
Delete 36512448584 by disconnect
Delete 36512448824 by disconnect
Delete 36512448776 by disconnect
ClientThread 36514078520
/Users/waldemarlima/Downloads/new/www/dependencies/media/background.png 215514 36514078520
Connect 36514077848
Connect 36514084184
Connect 36514084280
Connect 36514084328
Connect 36514084376
Connect 36514084424
Data 36514084424
Data 36514084376
Data 36514084328
Data 36514084280
Data 36514084184
Data 36514077848
ClientThread 36514084424
Delete 36514078520 by disconnect
Delete 36512448728 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/jquery.injectCSS.js 6009 36514084424
Delete 36512448632 by disconnect
ClientThread 36514084328
ClientThread 36514084184
Delete 36512448680 by disconnect
ClientThread 36514084280
ClientThread 36514084376
ClientThread 36514077848
/Users/waldemarlima/Downloads/new/www/dependencies/jquery-ui.custom.min.js 89011 36514084376
Delete 36512451032 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/resources/blank.gif 43 36514084328
/Users/waldemarlima/Downloads/new/www/dependencies/seedrandom.min.js 1232 36514084280
/Users/waldemarlima/Downloads/new/www/dependencies/mousetrap.min.js 4696 36514084184
/Users/waldemarlima/Downloads/new/www/dependencies/interact.min.js 98204 36514077848
Delete 36512450984 by disconnect
Connect 36514078520
Connect 36514084232
Data 36514084232
Data 36514078520
ClientThread 36514084232
ClientThread 36514078520
Delete 36514084424 by disconnect
Delete 36514084376 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/jquery.blockUI.min.js 9262 36514078520
Delete 36514084328 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/mousetrap-global-bind.min.js 297 36514084232
Delete 36514084280 by disconnect
Delete 36514084184 by disconnect
Delete 36514077848 by disconnect
Connect 36514077848
Connect 36514084184
Data 36514084184
Data 36514077848
ClientThread 36514084184
Delete 36514084232 by disconnect
ClientThread 36514077848
Delete 36514078520 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/dgrid/css/images/ui-icons_222222_256x240.png 4369 36514084184
/Users/waldemarlima/Downloads/new/www/dependencies/themes/flat/close.png 198 36514077848
Delete 36514084184 by disconnect
Delete 36514077848 by disconnect
debug output (safari loading):

Code: Select all

Connect 47152416904
Data 47152416904
ClientThread 47152416904
/Users/waldemarlima/Downloads/new/www/index.html 1812 47152416904
Connect 47152416952
Connect 47152416760
Connect 47152416856
Connect 47152417720
Connect 47152417816
Connect 47152417096
Data 47152417096
Data 47152417816
ClientThread 47152417096
Data 47152417720
ClientThread 47152417816
Data 47152416856
ClientThread 47152417720
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/themes/flat/flat.css 146173 47152417096
Data 47152416760
/Users/waldemarlima/Downloads/new/www/dependencies/main.js 2564 47152417816
ClientThread 47152416856
/Users/waldemarlima/Downloads/new/www/dependencies/debug.js 6488 47152417720
Data 47152416952
ClientThread 47152416760
Delete 47152416904 by disconnect
ClientThread 47152416952
/Users/waldemarlima/Downloads/new/www/dependencies/platform.js 37198 47152416952
/Users/waldemarlima/Downloads/new/www/dependencies/init.js 2481 47152416760
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/dojo.js 598521 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed 8444 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
SendNetworkData failed -1 47152416856
Connect 47152416904
Connect 47152417144
Connect 47152417048
Connect 47152417000
Data 47152417000
Data 47152417048
ClientThread 47152417000
Data 47152417144
ClientThread 47152417048
ClientThread 47152417144
/Users/waldemarlima/Downloads/new/www/meucu.js 163471 47152417000
/Users/waldemarlima/Downloads/new/www/dependencies/themes/flat/window.css 2949 47152417048
Data 47152416904
/Users/waldemarlima/Downloads/new/www/dependencies/xdate.min.js 7244 47152417144
Delete 47152417096 by disconnect
Delete 47152417816 by disconnect
Delete 47152417720 by disconnect
Delete 47152416856 by disconnect
Delete 47152416760 by disconnect
Delete 47152416952 by disconnect
ClientThread 47152416904
/Users/waldemarlima/Downloads/new/www/dependencies/dojo/dgrid/css/dgrid.css 5994 47152416904
Connect 47152416952
Data 47152416952
ClientThread 47152416952
Delete 47152417000 by disconnect
Delete 47152417048 by disconnect
Delete 47152417144 by disconnect
Delete 47152416904 by disconnect
/Users/waldemarlima/Downloads/new/www/dependencies/media/background.png 215514 47152416952
Delete 47152416952 by disconnect
Apparently, there’s some inconsistency in Safari and its derivatives. Could it be related to the network packets?
infratec
Always Here
Always Here
Posts: 7766
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Simple HTTP Server crashes on linux/mac on stress test

Post by infratec »

You can try the following:
change:

Code: Select all

*Buffer = AllocateMemory(16348, #PB_Memory_NoClear)
to:

Code: Select all

*Buffer = AllocateMemory(4096, #PB_Memory_NoClear)
If this is not working, I have to add the logic for partly send data chunks.
User avatar
skinkairewalker
Addict
Addict
Posts: 824
Joined: Fri Dec 04, 2015 9:26 pm

Re: Simple HTTP Server crashes on linux/mac on stress test

Post by skinkairewalker »

infratec wrote: Fri Jan 02, 2026 12:20 pm You can try the following:
change:

Code: Select all

*Buffer = AllocateMemory(16348, #PB_Memory_NoClear)
to:

Code: Select all

*Buffer = AllocateMemory(4096, #PB_Memory_NoClear)
If this is not working, I have to add the logic for partly send data chunks.
Adding a Delay(1) above

Code: Select all

Until Res = Chunk Or *Parameter\Disconnected
made it work...

The question that intrigues me is: why the hell would a 1ms delay make the algorithm work??? :? :? :?
In my head, this doesn’t seem like a stable solution to me... xD

Would you know why this happens?

Code: Select all

    If Not *Parameter\Disconnected And Timeout > 0
      *Buffer = AllocateMemory(16348, #PB_Memory_NoClear)
      If *Buffer
        File = ReadFile(#PB_Any, Filename$, #PB_File_SharedRead)
        If File
          While Not Eof(File) And Not *Parameter\Disconnected
            Chunk = ReadData(File, *Buffer, MemorySize(*Buffer))
            If Chunk > 0
              Timeout = 1000
              Repeat
                Res = SendNetworkData(*Parameter\Client, *Buffer, Chunk)
                If Res < Chunk
                  Debug "SendNetworkData failed " + Str(Res) + " " + Str(*Parameter\Client)
                EndIf
                Timeout - 1
                If Timeout = 0
                  Debug "Timeout"
                  Break 2
                EndIf
                Delay(1) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<- FIX 
              Until Res = Chunk Or *Parameter\Disconnected
            EndIf
          Wend
          CloseFile(File)
        Else
          Debug "File not open " + Str(*Parameter\Client)
        EndIf
        FreeMemory(*Buffer)
      Else
        Debug "No file buffer " + Str(*Parameter\Client)
      EndIf
      
    EndIf
User avatar
idle
Always Here
Always Here
Posts: 6130
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Simple HTTP Server crashes on linux/mac on stress test

Post by idle »

it needs a delay so any send error can clear on the socket. Most of the time a socket fails to send when you fill the send buffer and it blocks returning -1 and sets the socket error to EAGAIN or WSAWouldBlock
PB doesn't check the socket error to see if you can continue sending, so when you get an EAGAIN is means you should delay a bit and continue sending.


You can try these wrapper functions in place of Sendnetworkdata and ReceiveNetworkData
it returns total sent or 0 on error

Code: Select all

 ;-Extra functions 
#PB_Network_Error_Fatal = -1 
#PB_Network_Error_timeout = -2 
#PB_Network_Error_Dropped = -3 
#PB_Network_Error_Memory = -4 

Procedure Atomic_Server_NetworkErrorContinue(ID,val=0) 
  Protected ret,error.l
  
  #WSA_IO_INCOMPLETE = 996
  #WSA_IO_PENDING = 997
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows 
      #WSAEINTR = 10004
      #WSAEMFILE = 10024
      #WSAEWOULDBLOCK = 10035
      #WSAEINPROGRESS = 10036
      #WSAEALREADY = 10037
    CompilerCase #PB_OS_Linux
      #WSAEINTR = 4         ; EINTR 
      #WSAEMFILE = 17       ; ENOFILE 
      #WSAEWOULDBLOCK = 11  ; Eagain  
      #WSAEINPROGRESS = 115 ; EINPROGRESS
      #WSAEALREADY = 114    ; EALREADY 
    CompilerCase #PB_OS_MacOS
      #WSAEINTR = 4         ; EINTR 
      #WSAEMFILE = 24       ; EMFILE 
      #WSAEWOULDBLOCK = 35  ; EWOULDBLOCK = EAGAIN  
      #WSAEINPROGRESS = 36  ; EINPROGRESS
      #WSAEALREADY = 37     ; EALREADY 
  CompilerEndSelect
    
  #TLS_WANT_POLLIN  = -2
  #TLS_WANT_POLLOUT = -3
    
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows 
    error = WSAGetLastError_()
  CompilerElse 
    CompilerIf #PB_Compiler_Backend = #PB_Backend_C
      !#include "errno.h"
      !extern int errno;
      !v_error=errno;
    CompilerElse
      error = PeekL(__errno_location()) 
    CompilerEndIf 
  CompilerEndIf
  
  If val = #TLS_WANT_POLLIN
     Debug "#TLS_WANT_POLLIN"
    ProcedureReturn  1
  EndIf   
  If val = #TLS_WANT_POLLOUT  
     Debug "#TLS_WANT_POLLOUT"
    ProcedureReturn 1 
  EndIf   
  
  Select error 
    Case 0 
      ret = 0
       Debug "None " + Str(val) 
    Case  #WSAEWOULDBLOCK  
      ret = 1 
      Debug "#WSAEWOULDBLOCK"
    Case  #WSAEINPROGRESS   
      Debug "#WSAEINPROGRESS"
      ret = 1  
    Case  #WSAEALREADY  
      Debug "#WSAEALREADY"
      ret = 1  
    Case  #WSA_IO_INCOMPLETE
      Debug "#WSA_IO_INCOMPLETE"
      ret =1   
    Case  #WSA_IO_PENDING
      Debug "#WSA_IO_PENDING"
      ret = 1  
    Case  #WSAEMFILE 
      ret =1 
      Debug "#WSAEMFILE"
    Default 
      Debug error   
  EndSelect   
  
  ProcedureReturn ret 
  
EndProcedure  

Procedure Atomic_Server_ReceiveNetworkDataEx(clientId,len,timeout=15000,mutex=0,*error.Integer=0) 
  
  Protected result,recived,recvTimeout,tlen,bfirst=1
  
  If len > 0 
    Protected *buffer = AllocateMemory(len)
    If *buffer 
      
      recvTimeout=ElapsedMilliseconds()+timeout   
      
      Repeat
        If result > 0
           *buffer = ReAllocateMemory(*buffer, recived + len) 
        EndIf 
        If *buffer 
          If mutex 
            Repeat 
              If TryLockMutex(mutex)
                Result = ReceiveNetworkData(clientId,*buffer+recived, len) 
                If result < 0 
                  If Atomic_Server_NetworkErrorContinue(clientId,result) 
                    Delay(10)
                  Else 
                    
                    UnlockMutex(mutex)
                    FreeMemory(*buffer)
                    If *error 
                      *error\i = #PB_Network_Error_Fatal
                    EndIf   
                    ProcedureReturn 0
                  EndIf 
                EndIf   
                UnlockMutex(mutex) 
               
                Break 
              Else 
                Delay(10)
              EndIf   
            Until  ElapsedMilliseconds() > recvTimeout  
          Else       
            Result = ReceiveNetworkData(clientId,*buffer+recived, len)
            If result < 0 
              If Atomic_Server_NetworkErrorContinue(clientId,result) 
                Delay(10)
                Continue 
              Else 
                FreeMemory(*buffer)
                If *error 
                  *error\i = #PB_Network_Error_Fatal
                EndIf   
                Delay(10)
                ProcedureReturn 0
              EndIf 
            EndIf   
          EndIf   
          
          If result > 0 
            recived+result  
            recvTimeout = ElapsedMilliseconds() + timeout
          ElseIf result = 0 
            FreeMemory(*buffer)
            If *error 
              *error\i = #PB_Network_Error_Dropped 
            EndIf   
            ProcedureReturn 0
          EndIf   
        Else 
          If *error 
            *error\i = #PB_Network_Error_Memory 
          EndIf   
          ProcedureReturn 0
        EndIf   
        
        If ElapsedMilliseconds() > recvTimeout    
          FreeMemory(*buffer)
          If *error 
            *error\i = #PB_Network_Error_timeout 
          EndIf   
          ProcedureReturn 0
        EndIf 
        Delay(0) 
      Until result <> len   
      
      ProcedureReturn *buffer
      
    EndIf 
  EndIf 
  
EndProcedure   

Procedure Atomic_Server_SendNetworkDataEX(clientId,*buffer,len,timeout=15000,mutex=0,*error.Integer=0) 
  
  Protected  totalSent,tryLen,sendLen,sendTimeout
  
  sendTimeout = ElapsedMilliseconds() + timeout
  Repeat
    
    tryLen = len - totalSent
    If tryLen > len 
      tryLen = len 
    EndIf
    If mutex 
      Repeat 
        If TryLockMutex(mutex)  
          sendLen = SendNetworkData(clientId, *Buffer+totalSent,tryLen)
          If sendLen < 0 
            If Atomic_Server_NetworkErrorContinue(clientId,sendLen) 
              Delay(10) 
            Else 
            If *error 
               *error\i = #PB_Network_Error_Fatal
            EndIf   
             Debug Str(totalsent) + " " + Str(trylen) + " " + Str(len) 
             UnlockMutex(mutex)
             ProcedureReturn 0
            EndIf 
          EndIf 
          UnlockMutex(mutex) 
          Break 
        Else 
          Delay(10)
        EndIf 
      Until ElapsedMilliseconds() > sendTimeout 
    Else 
      sendLen = SendNetworkData(clientId, *Buffer+totalSent,tryLen)
      If sendLen < 0 
        If Atomic_Server_NetworkErrorContinue(clientId,sendLen) 
          Delay(10) 
        Else 
          If *error 
            *error\i = #PB_Network_Error_Fatal
          EndIf   
           Debug Str(totalsent) + " " + Str(trylen) + " " + Str(len) 
          ProcedureReturn 0
        EndIf 
      EndIf 
    EndIf   
    
    If sendLen > 0
      totalSent + sendLen
      sendLen = 0 
      sendTimeout = ElapsedMilliseconds() + timeout
    ElseIf sendLen = 0 
      If *error 
        *error\i = #PB_Network_Error_Dropped  
      EndIf   
      ProcedureReturn 0 
    EndIf 
    
    If ElapsedMilliseconds() > sendTimeout
      If *error 
        *error\i = #PB_Network_Error_timeout 
      EndIf   
      ProcedureReturn 0
    EndIf 
    
    Delay(1) 
    
  Until totalSent >= len 
  
  ProcedureReturn totalSent 
  
EndProcedure   
User avatar
skinkairewalker
Addict
Addict
Posts: 824
Joined: Fri Dec 04, 2015 9:26 pm

Re: Simple HTTP Server crashes on linux/mac on stress test

Post by skinkairewalker »

idle wrote: Sat Jan 03, 2026 6:16 am it needs a delay so any send error can clear on the socket. Most of the time a socket fails to send when you fill the send buffer and it blocks returning -1 and sets the socket error to EAGAIN or WSAWouldBlock
PB doesn't check the socket error to see if you can continue sending, so when you get an EAGAIN is means you should delay a bit and continue sending.


You can try these wrapper functions in place of Sendnetworkdata and ReceiveNetworkData
it returns total sent or 0 on error

Code: Select all

 ;-Extra functions 
#PB_Network_Error_Fatal = -1 
#PB_Network_Error_timeout = -2 
#PB_Network_Error_Dropped = -3 
#PB_Network_Error_Memory = -4 

Procedure Atomic_Server_NetworkErrorContinue(ID,val=0) 
  Protected ret,error.l
  
  #WSA_IO_INCOMPLETE = 996
  #WSA_IO_PENDING = 997
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Windows 
      #WSAEINTR = 10004
      #WSAEMFILE = 10024
      #WSAEWOULDBLOCK = 10035
      #WSAEINPROGRESS = 10036
      #WSAEALREADY = 10037
    CompilerCase #PB_OS_Linux
      #WSAEINTR = 4         ; EINTR 
      #WSAEMFILE = 17       ; ENOFILE 
      #WSAEWOULDBLOCK = 11  ; Eagain  
      #WSAEINPROGRESS = 115 ; EINPROGRESS
      #WSAEALREADY = 114    ; EALREADY 
    CompilerCase #PB_OS_MacOS
      #WSAEINTR = 4         ; EINTR 
      #WSAEMFILE = 24       ; EMFILE 
      #WSAEWOULDBLOCK = 35  ; EWOULDBLOCK = EAGAIN  
      #WSAEINPROGRESS = 36  ; EINPROGRESS
      #WSAEALREADY = 37     ; EALREADY 
  CompilerEndSelect
    
  #TLS_WANT_POLLIN  = -2
  #TLS_WANT_POLLOUT = -3
    
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows 
    error = WSAGetLastError_()
  CompilerElse 
    CompilerIf #PB_Compiler_Backend = #PB_Backend_C
      !#include "errno.h"
      !extern int errno;
      !v_error=errno;
    CompilerElse
      error = PeekL(__errno_location()) 
    CompilerEndIf 
  CompilerEndIf
  
  If val = #TLS_WANT_POLLIN
     Debug "#TLS_WANT_POLLIN"
    ProcedureReturn  1
  EndIf   
  If val = #TLS_WANT_POLLOUT  
     Debug "#TLS_WANT_POLLOUT"
    ProcedureReturn 1 
  EndIf   
  
  Select error 
    Case 0 
      ret = 0
       Debug "None " + Str(val) 
    Case  #WSAEWOULDBLOCK  
      ret = 1 
      Debug "#WSAEWOULDBLOCK"
    Case  #WSAEINPROGRESS   
      Debug "#WSAEINPROGRESS"
      ret = 1  
    Case  #WSAEALREADY  
      Debug "#WSAEALREADY"
      ret = 1  
    Case  #WSA_IO_INCOMPLETE
      Debug "#WSA_IO_INCOMPLETE"
      ret =1   
    Case  #WSA_IO_PENDING
      Debug "#WSA_IO_PENDING"
      ret = 1  
    Case  #WSAEMFILE 
      ret =1 
      Debug "#WSAEMFILE"
    Default 
      Debug error   
  EndSelect   
  
  ProcedureReturn ret 
  
EndProcedure  

Procedure Atomic_Server_ReceiveNetworkDataEx(clientId,len,timeout=15000,mutex=0,*error.Integer=0) 
  
  Protected result,recived,recvTimeout,tlen,bfirst=1
  
  If len > 0 
    Protected *buffer = AllocateMemory(len)
    If *buffer 
      
      recvTimeout=ElapsedMilliseconds()+timeout   
      
      Repeat
        If result > 0
           *buffer = ReAllocateMemory(*buffer, recived + len) 
        EndIf 
        If *buffer 
          If mutex 
            Repeat 
              If TryLockMutex(mutex)
                Result = ReceiveNetworkData(clientId,*buffer+recived, len) 
                If result < 0 
                  If Atomic_Server_NetworkErrorContinue(clientId,result) 
                    Delay(10)
                  Else 
                    
                    UnlockMutex(mutex)
                    FreeMemory(*buffer)
                    If *error 
                      *error\i = #PB_Network_Error_Fatal
                    EndIf   
                    ProcedureReturn 0
                  EndIf 
                EndIf   
                UnlockMutex(mutex) 
               
                Break 
              Else 
                Delay(10)
              EndIf   
            Until  ElapsedMilliseconds() > recvTimeout  
          Else       
            Result = ReceiveNetworkData(clientId,*buffer+recived, len)
            If result < 0 
              If Atomic_Server_NetworkErrorContinue(clientId,result) 
                Delay(10)
                Continue 
              Else 
                FreeMemory(*buffer)
                If *error 
                  *error\i = #PB_Network_Error_Fatal
                EndIf   
                Delay(10)
                ProcedureReturn 0
              EndIf 
            EndIf   
          EndIf   
          
          If result > 0 
            recived+result  
            recvTimeout = ElapsedMilliseconds() + timeout
          ElseIf result = 0 
            FreeMemory(*buffer)
            If *error 
              *error\i = #PB_Network_Error_Dropped 
            EndIf   
            ProcedureReturn 0
          EndIf   
        Else 
          If *error 
            *error\i = #PB_Network_Error_Memory 
          EndIf   
          ProcedureReturn 0
        EndIf   
        
        If ElapsedMilliseconds() > recvTimeout    
          FreeMemory(*buffer)
          If *error 
            *error\i = #PB_Network_Error_timeout 
          EndIf   
          ProcedureReturn 0
        EndIf 
        Delay(0) 
      Until result <> len   
      
      ProcedureReturn *buffer
      
    EndIf 
  EndIf 
  
EndProcedure   

Procedure Atomic_Server_SendNetworkDataEX(clientId,*buffer,len,timeout=15000,mutex=0,*error.Integer=0) 
  
  Protected  totalSent,tryLen,sendLen,sendTimeout
  
  sendTimeout = ElapsedMilliseconds() + timeout
  Repeat
    
    tryLen = len - totalSent
    If tryLen > len 
      tryLen = len 
    EndIf
    If mutex 
      Repeat 
        If TryLockMutex(mutex)  
          sendLen = SendNetworkData(clientId, *Buffer+totalSent,tryLen)
          If sendLen < 0 
            If Atomic_Server_NetworkErrorContinue(clientId,sendLen) 
              Delay(10) 
            Else 
            If *error 
               *error\i = #PB_Network_Error_Fatal
            EndIf   
             Debug Str(totalsent) + " " + Str(trylen) + " " + Str(len) 
             UnlockMutex(mutex)
             ProcedureReturn 0
            EndIf 
          EndIf 
          UnlockMutex(mutex) 
          Break 
        Else 
          Delay(10)
        EndIf 
      Until ElapsedMilliseconds() > sendTimeout 
    Else 
      sendLen = SendNetworkData(clientId, *Buffer+totalSent,tryLen)
      If sendLen < 0 
        If Atomic_Server_NetworkErrorContinue(clientId,sendLen) 
          Delay(10) 
        Else 
          If *error 
            *error\i = #PB_Network_Error_Fatal
          EndIf   
           Debug Str(totalsent) + " " + Str(trylen) + " " + Str(len) 
          ProcedureReturn 0
        EndIf 
      EndIf 
    EndIf   
    
    If sendLen > 0
      totalSent + sendLen
      sendLen = 0 
      sendTimeout = ElapsedMilliseconds() + timeout
    ElseIf sendLen = 0 
      If *error 
        *error\i = #PB_Network_Error_Dropped  
      EndIf   
      ProcedureReturn 0 
    EndIf 
    
    If ElapsedMilliseconds() > sendTimeout
      If *error 
        *error\i = #PB_Network_Error_timeout 
      EndIf   
      ProcedureReturn 0
    EndIf 
    
    Delay(1) 
    
  Until totalSent >= len 
  
  ProcedureReturn totalSent 
  
EndProcedure   
Thanks for the explanation, that makes a lot more sense now.
The Delay() isn’t about random instability, but about giving the socket time to recover when the send buffer is full and it returns EAGAIN / WOULD_BLOCK. Since PureBasic doesn’t properly check the socket error to continue sending, the delay becomes necessary.

The wrapper functions you shared are very helpful and clearly show how to handle these transient errors correctly instead of treating them as fatal.
I appreciate you taking the time to explain it and share the code 👍
Post Reply