Block on END
Block on END
Dear all, i've a strange problem on a software compiled with latest v6.02 LTS, sometimes do not close on end remain process blocked, to better explain is a window that on event show a messagerequester for confirm to close, if user confirm the command "end" is called, i've also tried to free all resources before calling "end", i've also tried to insert a "calldebugger" before the end to better check, calldebugger is called and when i step on "end" program do not close also in IDE and i cannot pause it, is completely locked.
The problem is also randomic in both compiled and in IDE, sometimes software close without problem, sometimes i've got this problem
Of couse killing from task manager resolve the problem.
Any ideas ?
The problem is also randomic in both compiled and in IDE, sometimes software close without problem, sometimes i've got this problem
Of couse killing from task manager resolve the problem.
Any ideas ?
Re: Block on END
Me trying to help you without any hint of code:


Good morning, that's a nice tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: Block on END
Which operating system.
macOS and Linux do not like it when threads are still running in the background.
macOS and Linux do not like it when threads are still running in the background.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Block on END
Windows 11
Code: Select all
If MessageRequester ( Softname , "Sure to close ?" , #PB_MessageRequester_YesNo ) = #PB_MessageRequester_Yes
If IsThread ( CleanThread )
KillThread ( CleanThread )
EndIf
If IsThread ( AutoPilotThread )
KillThread ( AutoPilotThread )
EndIf
If IsThread ( AutoRetryThread )
KillThread ( AutoRetryThread )
EndIf
UpdateDB ()
UpdateFile ()
If IsDatabase ( 0 )
CloseDatabase ( 0 )
EndIf
If IsDatabase ( 1 )
CloseDatabase ( 1 )
EndIf
Delay ( 1000 )
ReleaseMutex_ ( Mutex )
End
EndIf
Re: Block on END
Don't use KillThread, instead set a global variable or something and handle it within the thread!
Also, your code isn't runnable.
Also, your code isn't runnable.
Good morning, that's a nice tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: Block on END
i cannot use global variable to manage the thread because they are totally indipendent from main code and contain a lot of delay for processing jobs scheduled, if i set a variable for inform the thread that must end without kill i need to wait the last delay that is currently running in the thread, for example if sleep is 1 minute so the main window must wait 1 minute to close and this is totally unacceptable.jacdelad wrote: Mon Jul 24, 2023 2:44 pm Don't use KillThread, instead set a global variable or something and handle it within the thread!
Also, your code isn't runnable.
My code isn't runnable but work perfectly except the program end ? really interesting, so explain me what's wrong
Re: Block on END
Build a loop with 100ms delay and query the end of the programm in this loop.
Where is a owner of Mutex ?
MSDN:
Where is a owner of Mutex ?
MSDN:
Remarks
The ReleaseMutex function fails if the calling thread does not own the mutex object.
A thread obtains ownership of a mutex either by creating it with the bInitialOwner parameter set to TRUE or by specifying its handle in a call to one of the wait functions. When the thread no longer needs to own the mutex object, it calls the ReleaseMutex function so that another thread can acquire ownership.
A thread can specify a mutex that it already owns in a call to one of the wait functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex one time for each time that it obtained ownership (either through CreateMutex or a wait function).
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Block on END
it's the main thread that initialize the mutex after the global variable declaration
do you think that thread can cause the end failure ?
it's also strange that also the debugger freeze
testing:
do you think that thread can cause the end failure ?
it's also strange that also the debugger freeze
testing:
Code: Select all
If MessageRequester ( Softname , "Sure to close ?" , #PB_MessageRequester_YesNo ) = #PB_MessageRequester_Yes
CloseThread = #True
Repeat
Delay ( 100 )
Until IsThread ( CleanThread ) = 0 And IsThread ( AutoPilotThread ) = 0 And IsThread ( AutoRetryThread ) = 0
UpdateDB ()
UpdateFile ()
If IsDatabase ( 0 )
CloseDatabase ( 0 )
EndIf
If IsDatabase ( 1 )
CloseDatabase ( 1 )
EndIf
ReleaseMutex_ ( Mutex )
CallDebugger
End
EndIf
Last edited by ALAN-MHz on Mon Jul 24, 2023 4:00 pm, edited 1 time in total.
Re: Block on END
But that's the way it will work. Also, you can chop your long delay into shorter delays (and process the rest of your stuff after n-count of processed delays) to be able to process the termination variable.ALAN-MHz wrote: Mon Jul 24, 2023 3:03 pmi cannot use global variable to manage the thread because they are totally indipendent from main code and contain a lot of delay for processing jobs scheduled, if i set a variable for inform the thread that must end without kill i need to wait the last delay that is currently running in the thread, for example if sleep is 1 minute so the main window must wait 1 minute to close and this is totally unacceptable.jacdelad wrote: Mon Jul 24, 2023 2:44 pm Don't use KillThread, instead set a global variable or something and handle it within the thread!
Also, your code isn't runnable.
My code isn't runnable but work perfectly except the program end ? really interesting, so explain me what's wrong
Good morning, that's a nice tnetennba!
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Re: Block on END
But not the loop when the program ends, but in the thread.
Code: Select all
;-TOP
CompilerIf Not #PB_Compiler_Thread
CompilerError "Use Compiler Option ThreadSafe"
CompilerEndIf
#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"
Enumeration Windows
#Main
EndEnumeration
Enumeration MenuBar
#MainMenu
EndEnumeration
Enumeration MenuItems
#MainMenuAbout
#MainMenuExit
EndEnumeration
Enumeration Gadgets
#MainList
EndEnumeration
Enumeration StatusBar
#MainStatusBar
EndEnumeration
; ----
Structure udtMyThread
ThreadID.i
Exit.i
Name.s
Pause.i
EndStructure
Global.udtMyThread th1, th2
Procedure MyThread(*Data.udtMyThread)
Protected time
With *Data
Debug "Init Thread " + \Name
Repeat
; Working
Debug "Do any ... " + \Name
For i = 1 To 100
; Check exit
If \Exit
Debug "Cancel Thread " + \Name
Break
EndIf
; Simulate processing
Delay(8)
Next
; Pause
time = ElapsedMilliseconds()
Repeat
; Check exit
If \Exit
Break 2
EndIf
Delay(100)
If ElapsedMilliseconds() - time > \Pause
Break
EndIf
ForEver
ForEver
Debug "Exit Thread " + \Name
EndWith
EndProcedure
; ----
Procedure UpdateWindow()
Protected dx, dy
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
; Resize gadgets
ResizeGadget(#MainList, 0, 0, dx, dy)
EndProcedure
Procedure Main()
Protected dx, dy
#MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
; Menu
CreateMenu(#MainMenu, WindowID(#Main))
MenuTitle("&File")
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
MenuItem(#PB_Menu_About, "")
CompilerElse
MenuItem(#MainMenuAbout, "About")
CompilerEndIf
; Menu File Items
CompilerIf Not #PB_Compiler_OS = #PB_OS_MacOS
MenuBar()
MenuItem(#MainMenuExit, "E&xit")
CompilerEndIf
; StatusBar
CreateStatusBar(#MainStatusBar, WindowID(#Main))
AddStatusBarField(#PB_Ignore)
; Gadgets
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
ListViewGadget(#MainList, 0, 0, dx, dy)
; Bind Events
BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
th1\Name = "MyThread 1"
th1\Pause = 5000
th1\ThreadID = CreateThread(@MyThread(), @th1)
Delay(100)
th2\Name = "MyThread 2"
th2\Pause = 7500
th2\ThreadID = CreateThread(@MyThread(), @th2)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
Break
EndSelect
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
CompilerEndIf
Case #MainMenuExit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
Case #MainMenuAbout
MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #MainList
Select EventType()
Case #PB_EventType_Change
;
EndSelect
EndSelect
EndSelect
ForEver
th1\Exit = #True
th2\Exit = #True
If WaitThread(th1\ThreadID, 5000) = 0
KillThread(th1\ThreadID)
Debug "Thread th1 killed"
EndIf
If WaitThread(th2\ThreadID, 5000) = 0
KillThread(th2\ThreadID)
Debug "Thread th2 killed"
EndIf
EndIf
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Block on END
That won't help when a thread is showing a MessageRequester() or InputRequester(), etc. KillThread() is needed in such cases.jacdelad wrote: Mon Jul 24, 2023 2:44 pmDon't use KillThread, instead set a global variable or something and handle it within the thread
Re: Block on END
threads seems more stable with a global variable for closing them, i test more and more times to be sure because as told the problem is randomic
thanks to all for suggestions
thanks to all for suggestions