Wishes for PureBasic

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Wishes for PureBasic

Post 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... :(
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
Kukulkan
Addict
Addict
Posts: 1396
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Wishes for PureBasic

Post 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 :-)
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Wishes for PureBasic

Post by IdeasVacuum »

I think the work-around, a DIY CanvasGadget() progress bar, is far better anyway.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Wishes for PureBasic

Post 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
User avatar
Kukulkan
Addict
Addict
Posts: 1396
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Wishes for PureBasic

Post 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
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Wishes for PureBasic

Post 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.
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Wishes for PureBasic

Post 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
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Wishes for PureBasic

Post by Danilo »

bbanelli wrote:please look at this behavior.

http://youtu.be/sduvYg9wOyo?hd=1
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.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Wishes for PureBasic

Post 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.
Last edited by Danilo on Tue Sep 16, 2014 8:13 am, edited 1 time in total.
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Wishes for PureBasic

Post 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.
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Wishes for PureBasic

Post 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?
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Wishes for PureBasic

Post 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'.
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Wishes for PureBasic

Post 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
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Wishes for PureBasic

Post 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...
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
Post Reply