Page 1 of 1

App sleeping?

Posted: Fri Oct 08, 2021 2:40 pm
by deseven
Hi guys. I'm on 10.15.7 with PB 5.73 and the app I'm currently writing features a very simple HTTP server to provide an API.

It works fine most of the time, but today I noticed that sometimes it fails to process some requests quickly or fails to process them at all. I started digging and found out that WaitWindowEvent() stops firing after some time, and what is even worse, Delay() in threads also returns much much slower.

Consider this example:

Code: Select all

OpenWindow(0,0,0,400,300,"test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)

Procedure simpleThread(dummy)
  Repeat
    Delay(900)
    Debug "thread"
  ForEver
EndProcedure

CreateThread(@simpleThread(),0)

Repeat
  ev = WaitWindowEvent(900)
  Debug "event"
Until ev = #PB_Event_CloseWindow
Run it and minimize the window, after a minute or so, you start getting debug messages much slower and without any fixed interval.

Here's the video showing it on my system:
https://d7.wtf/s/Screen%20Recording%202 ... .27.08.mp4

So what this actually is? Is it a bug? Is it some sort of a sleeping mechanism in macOS? If so, how to avoid it?

Re: App sleeping?

Posted: Fri Oct 08, 2021 4:51 pm
by mk-soft
macOS NapStop is the problem ...

Solution:

Code: Select all

;--- MacOS NapStop

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  ; Author : Danilo
  ; Date   : 25.03.2014
  ; Link   : https://www.purebasic.fr/english/viewtopic.php?f=19&t=58828
  ; Info   : NSActivityOptions is a 64bit typedef - use it with quads (.q) !!!
  
  #NSActivityIdleDisplaySleepDisabled             = 1 << 40
  #NSActivityIdleSystemSleepDisabled              = 1 << 20
  #NSActivitySuddenTerminationDisabled            = (1 << 14)
  #NSActivityAutomaticTerminationDisabled         = (1 << 15)
  #NSActivityUserInitiated                        = ($00FFFFFF | #NSActivityIdleSystemSleepDisabled)
  #NSActivityUserInitiatedAllowingIdleSystemSleep = (#NSActivityUserInitiated & ~#NSActivityIdleSystemSleepDisabled)
  #NSActivityBackground                           = $000000FF
  #NSActivityLatencyCritical                      = $FF00000000
  
  Procedure BeginWork(Option.q, Reason.s= "MyReason")
    Protected NSProcessInfo = CocoaMessage(0,0,"NSProcessInfo processInfo")
    If NSProcessInfo
      ProcedureReturn CocoaMessage(0, NSProcessInfo, "beginActivityWithOptions:@", @Option, "reason:$", @Reason)
    EndIf
  EndProcedure
  
  Procedure EndWork(Activity)
    Protected NSProcessInfo = CocoaMessage(0, 0, "NSProcessInfo processInfo")
    If NSProcessInfo
      CocoaMessage(0, NSProcessInfo, "endActivity:", Activity)
    EndIf
  EndProcedure
CompilerEndIf


Global ExitThread

OpenWindow(0,0,0,400,300,"test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)

Procedure simpleThread(dummy)
  
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    Protected StopNap = BeginWork(#NSActivityLatencyCritical | #NSActivityUserInitiated, "MyReason")
  CompilerEndIf
  
  Repeat
    Delay(900)
    Debug "thread"
  Until ExitThread
  
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    EndWork(StopNap)
  CompilerEndIf
  
EndProcedure

hThread = CreateThread(@simpleThread(),0)

Repeat
  ev = WaitWindowEvent(900)
  Debug "event"
Until ev = #PB_Event_CloseWindow

ExitThread = #True
If WaitThread(hThread, 2000) = 0
  KillThread(hThread)
EndIf

Re: App sleeping?

Posted: Fri Oct 08, 2021 5:44 pm
by deseven
Oh, thank you so much!

By the look of things it applies to the whole process, not to individual thread. But that's okay, I'll at least be able to read docs on that, now that I know that it's controllable.

Re: App sleeping?

Posted: Sat Oct 09, 2021 5:38 pm
by deseven
Okay, 2 things:
1. beginActivity actually can't be called from the main thread, but it does propagate to it too.
2. NSActivityBackground is enough to get your app working.

All in all, I've got it working, thanks again!