Page 2 of 2
Re: Wishes for PureBasic
Posted: Sun Sep 14, 2014 6:38 pm
by bbanelli
Kukulkan wrote:I tried updating a progress bar and if it worked on Windows, it crashed on MacOS. After some changes it crashed on Linux and Windows. I've had to do the progress bar in the main thread and the work in a separate thread (work was done in some DLL, so no manual progress was possible). A lot of code for just some progress bar...
Wow, I really didn't know this - just tried with some of my examples and it crashes randomly for about any Gadget modified from a thread.
How come this doesn't happen in Windows? This is bad...

Re: Wishes for PureBasic
Posted: Mon Sep 15, 2014 10:56 am
by Kukulkan
...just tried with some of my examples and it crashes randomly for about any Gadget modified from a thread
Yes, this is why it was on my wish list

Re: Wishes for PureBasic
Posted: Mon Sep 15, 2014 12:38 pm
by IdeasVacuum
I think the work-around, a DIY CanvasGadget() progress bar, is far better anyway.
Re: Wishes for PureBasic
Posted: Tue Sep 16, 2014 6:50 am
by Danilo
Kukulkan wrote:...just tried with some of my examples and it crashes randomly for about any Gadget modified from a thread
Yes, this is why it was on my wish list

Code: Select all
#Event_ThreadMessage = #PB_Event_FirstCustomValue
#EventType_UpdateProgressbar = #PB_EventType_FirstCustomValue
Procedure WorkerThread(value)
For i = 1 To 100
PostEvent(#Event_ThreadMessage,0,value,#EventType_UpdateProgressbar,i)
Delay( 25 + Random(300) )
Next
EndProcedure
Procedure OnThreadMessage()
Select EventType()
Case #EventType_UpdateProgressbar
SetGadgetState( EventGadget(), EventData() )
EndSelect
EndProcedure
If OpenWindow(0, 0, 0, 400, 330, "Thread Message Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
BindEvent(#Event_ThreadMessage,@OnThreadMessage())
For i = 0 To 9
ProgressBarGadget(i, 10, 20+i*30, 380, 20, 0, 100)
CreateThread( @WorkerThread(), i )
Next
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Re: Wishes for PureBasic
Posted: Tue Sep 16, 2014 7:26 am
by Kukulkan
Hi Danilo,
nice try, but it does not work if your main thread is busy with something. In my case, some external DLL is doing stuff. This blocks the main thread with some work and there is no, or only reduced, message handling during this time. If my main loop would run, I would not need a thread for updating the screen.
Replace
Code: Select all
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
with
Code: Select all
Repeat
; do something slow in external DLL
Delay(2000)
Until WaitWindowEvent() = #PB_Event_CloseWindow
I currently run the DLL in my thread to do the progress bar in the main thread. But I don't like this solution.
Kukulkan
Re: Wishes for PureBasic
Posted: Tue Sep 16, 2014 7:34 am
by Danilo
Kukulkan wrote:I currently run the DLL in my thread to do the progress bar in the main thread. But I don't like this solution.
Should be the correct way, because the main event loop should always run.
Otherwise you get a "(not responding)" window title after a while and Windows thinks the app is hanging.
Re: Wishes for PureBasic
Posted: Tue Sep 16, 2014 7:38 am
by bbanelli
Danilo wrote:Code: Select all
#Event_ThreadMessage = #PB_Event_FirstCustomValue
#EventType_UpdateProgressbar = #PB_EventType_FirstCustomValue
Procedure WorkerThread(value)
For i = 1 To 100
PostEvent(#Event_ThreadMessage,0,value,#EventType_UpdateProgressbar,i)
Delay( 25 + Random(300) )
Next
EndProcedure
Procedure OnThreadMessage()
Select EventType()
Case #EventType_UpdateProgressbar
SetGadgetState( EventGadget(), EventData() )
EndSelect
EndProcedure
If OpenWindow(0, 0, 0, 400, 330, "Thread Message Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
BindEvent(#Event_ThreadMessage,@OnThreadMessage())
For i = 0 To 9
ProgressBarGadget(i, 10, 20+i*30, 380, 20, 0, 100)
CreateThread( @WorkerThread(), i )
Next
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Hi Danilo,
please look at this behavior.
http://youtu.be/sduvYg9wOyo?hd=1
Am I doing something wrong or are additional settings needed?
With my best,
Bruno
Re: Wishes for PureBasic
Posted: Tue Sep 16, 2014 7:46 am
by Danilo
I tested with Windows and Mac OS X. Don't know about Linux, maybe a bug? Could also be your virtual machine.
PostEvent() wrote:Remarks
This command can be very useful to communicate between threads and the main event loop.
For example, a thread can send a custom event when it has finished its processing (with an associated data),
so the main loop will get it and further processing can be done.
Re: Wishes for PureBasic
Posted: Tue Sep 16, 2014 8:06 am
by Danilo
Just tried with Linux. You need to use:
Code: Select all
Repeat:Until WaitWindowEvent(1) = #PB_Event_CloseWindow
Looks like PostEvent() does not fire a real event, so WaitWindowEvent() does not get interupted.
With WaitWindowEvent(1) or another timeout value it works. Could be a bug on Linux.
EDIT:
And if you use compiler option "[X] Create threadsafe executable" on Linux, it just hangs again,
while it runs fine on Windows and Mac.
Re: Wishes for PureBasic
Posted: Tue Sep 16, 2014 8:12 am
by bbanelli
Danilo wrote:I tested with Windows and Mac OS X. Don't know about Linux, maybe a bug? Could also be your virtual machine.
This is quite interesting.
I have created executable and it shows same behavior on both Virtual machines. However, when running on "normal" machine next to me, that executable is working properly!
Nevertheless, after applying your fix in last post, it works in Virtual machines properly as well.
Thank you very much in any case, I will try rewriting my code to fit this Bind/Post event functions in hope to get threads work on all platforms.
Re: Wishes for PureBasic
Posted: Wed Sep 17, 2014 5:30 pm
by bbanelli
Danilo wrote:EDIT:
And if you use compiler option "[X] Create threadsafe executable" on Linux, it just hangs again,
while it runs fine on Windows and Mac.
Per your instructions, I have changed code of my application.
As you have said, it works perfectly on Windows and OS X, but when Threadsafe executable is activated on Linux (x64, didn't try with x86), application hangs. It works for some undefined period of time without
Threadsafe, but expectedly, it breaks after a while. Will this be escalated as a bug in this thread or a new one in Linux section should be posted?
Re: Wishes for PureBasic
Posted: Wed Sep 17, 2014 6:08 pm
by Danilo
bbanelli wrote:Will this be escalated as a bug in this thread or a new one in Linux section should be posted?
You should post a new bug report, including example. It would help when some of the Linux experts
could investigate and at least confirm the issue, if they 'wish for a better quality Linux compiler'.
Re: Wishes for PureBasic
Posted: Wed Sep 17, 2014 7:07 pm
by bbanelli
Danilo wrote:bbanelli wrote:Will this be escalated as a bug in this thread or a new one in Linux section should be posted?
You should post a new bug report, including example. It would help when some of the Linux experts
could investigate and at least confirm the issue, if they 'wish for a better quality Linux compiler'.
Here it is ->
http://www.forums.purebasic.com/english ... 23&t=60552
Regardless of that, thank you once again for pointing out Bind/PostEvent function, now my OS X software works perfectly with threads.
Best regards,
Bruno
Re: Wishes for PureBasic
Posted: Sun Sep 21, 2014 1:35 am
by bbanelli
Danilo wrote:Just tried with Linux. You need to use:
Code: Select all
Repeat:Until WaitWindowEvent(1) = #PB_Event_CloseWindow
Looks like PostEvent() does not fire a real event, so WaitWindowEvent() does not get interupted.
With WaitWindowEvent(1) or another timeout value it works. Could be a bug on Linux.
EDIT:
And if you use compiler option "[X] Create threadsafe executable" on Linux, it just hangs again,
while it runs fine on Windows and Mac.
Hi,
after some digging, take a look at this (rather trivial) example:
http://www.purebasic.fr/english/viewtop ... 12&t=45528
It seems to be working fine on Linux, haven't been able to provoke any undesirable behavior - and it is updating gadget from thread. I sure hope there will be some official clarification of this; if it is unsafe to update gadgets from threads on Linux, that requires fundamental change of code creation for multiOS projects.
Your example is fairly simple and returns some useful results from strace/gdb, so...