Hi together,
I ran into a problem:
I use OpenSerialPort() and MessageRequester() in a thread.
In windoof everything works fine.
In Linux I got reproducable crashes.
But it depence on ???
It's difficult to explain.
I had to implement several different serial protocols in the same program.
I managed it with pointers to procedures.
The pointer is set to the needed procedure and opened as thread.
Inside of the thread is always OpenSerialPort() and sometimes MessagerRequester()
The OpenWindow() stuff which was used is replaced with PostEvent().
2 procedures are working and 2 not.
They are nearly identical at the start where the crash happens.
One time I saw a message from Linux XInitThread was not called ... (or something similar)
If I run it inside the IDE I only get an 'executable is termiated ...'
I tried also Purifier ... no better results.
So please can someone tell me if MessageRequester() and OpenSerialPort() and ioctl_() are threadsafe ?
Bernd
MessageRequester() in a thread allowed or not
Re: MessageRequester() in a thread allowed or not
Never use a Requester in a thread!
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Re: MessageRequester() in a thread allowed or not
Save the message into a global variable and query the variables content in the main event loop. That works! You should never access GUI elements from another thread.
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
Re: MessageRequester() in a thread allowed or not
Ok, ok,
I change everything to:
Thank you very much, tomorrow I can try it.
Bernd
I change everything to:
Code: Select all
PostEvent(#EventShowMessageRequester, #MainWindow, 0, 0, @Text$)
WaitSemaphore(MessageRequesterSemaphore)
Bernd
Re: MessageRequester() in a thread allowed or not
I have made a small example for you, but you are so fast
Greetings - Thomas
Code: Select all
EnableExplicit
Structure MessageBox
Title.s
Text.s
Flag.i
EndStructure
#MyThreadEvent = #PB_Event_FirstCustomValue
Procedure MyThread(dummy)
Protected *mem.MessageBox = AllocateMemory(SizeOf(MessageBox))
Delay(5000)
*mem\Title = "My Title"
*mem\Text = "Hello world from Thread"
PostEvent(#MyThreadEvent, 0, -1, -1, *mem)
EndProcedure
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "")
Define Thread = CreateThread(@MyThread(), 0)
Define *mem.MessageBox
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
WaitThread(Thread, 6000)
Break
Case #MyThreadEvent
*mem = EventData()
MessageRequester(*mem\Title, *mem\Text, *mem\Flag)
FreeMemory(*mem)
EndSelect
ForEver
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Re: MessageRequester() in a thread allowed or not
Hi, I just noticed your posting on calling MessageRequester()'s from a thread.infratec wrote:Ok, ok,
I change everything to:Thank you very much, tomorrow I can try it.Code: Select all
PostEvent(#EventShowMessageRequester, #MainWindow, 0, 0, @Text$) WaitSemaphore(MessageRequesterSemaphore)
Bernd
My Windows app's do this without errors or lockups.
Was I just lucky?
My assumption is PB's MessageRequester() is modal or blocking in the Windows lib.
Not sure about Linux/MAC?
Searching this topic seems to give conflicting answers?
MessageBoxes and worker threads
I really want to avoid creating PostEvent()'s for modal dialog boxes called from my various threads.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: MessageRequester() in a thread allowed or not
Everything that has to do with GUI must always be processed in the MainThread.
With the MessageRequester via PostEvent to open I had a behaviour under MacOS which I didn't want to do to the user. This could open several times via thread.
So I block the requester in my module ThreadToGUI via a mutex.
Edit...
To open dialogs via threads its only wirk over PostEvent, because we can only create window and gadget inside the MainThread
With the MessageRequester via PostEvent to open I had a behaviour under MacOS which I didn't want to do to the user. This could open several times via thread.
So I block the requester in my module ThreadToGUI via a mutex.
Edit...
To open dialogs via threads its only wirk over PostEvent, because we can only create window and gadget inside the MainThread
Code: Select all
;-TOP
; Example ThreadToGUI SendEvent with open Dialog
IncludeFile "Modul_ThreadToGUI.pb"
UseModule ThreadToGUI
Enumeration
#Window
#Dialog
EndEnumeration
Enumeration
#Dialog_Ok
#Dialog_Cancel
#Dialog_List
EndEnumeration
;- Test
;- Constants
Enumeration #PB_Event_FirstCustomValue
#My_Event_OpenDialog
EndEnumeration
Structure udtDialogData
Array TextList.s(0)
EndStructure
Procedure Test(Null)
Protected result, index, daten.udtDialogData
Debug "Init Thread"
Dim daten\TextList(9)
For index = 0 To ArraySize(daten\TextList())
daten\TextList(index) = "Eintrag " + Str(index)
Next
Repeat
Delay(1000)
result = SendEvent(#My_Event_OpenDialog, 0, 0, 0, @daten)
If result >= 0
Debug "Result: " + daten\TextList(result)
Else
Debug "Abbruch!"
Break
EndIf
ForEver
Debug "Exit Thread"
EndProcedure
Procedure OpenDialog(*Daten.udtDialogData)
Protected index
If OpenWindow(#Dialog, #PB_Ignore, #PB_Ignore, 400, 300, "Example Threaded Dialog")
ListViewGadget(#Dialog_List, 5, 5, 380, 240)
ButtonGadget(#Dialog_Ok, 5, 260, 120, 25, "Ok")
ButtonGadget(#Dialog_Cancel, 270, 260, 120, 25, "Abbrechen")
For index = 0 To ArraySize(*Daten\TextList())
AddGadgetItem(#Dialog_List, index, *Daten\TextList(index))
Next
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure Main()
Protected MyEventOpenDialog, result
If OpenWindow(#Window, 0, 0, 400, 200, "Example SendEvent", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
UseModule ThreadToGUI
hThread = CreateThread(@Test(), #Null)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
If EventWindow() = #Window
exit = 1
EndIf
Case #PB_Event_Gadget
Select EventGadget()
Case #Dialog_Ok
result = GetGadgetState(#Dialog_List)
CloseWindow(#Dialog)
DispatchEvent(MyEventOpenDialog, result)
Case #Dialog_Cancel
CloseWindow(#Dialog)
result = -1
DispatchEvent(MyEventOpenDialog, result)
EndSelect
Case #My_Event_OpenDialog
MyEventOpenDialog = EventData()
OpenDialog(SendEventData(MyEventOpenDialog))
EndSelect
Until exit
If IsThread(hThread)
Debug "Thread läuft"
KillThread(hThread)
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: MessageRequester() in a thread allowed or not
So far, I have not had a case where more than 1 thread called a MessageRequester()?
I am confused by that scenario anyway, since how can the OS display more than 1 modal dialog?
Which 1 is the leader?
Do you have an example code with 2 threads each calling a MessageRequester()?
EDIT: haha, you posted too fast!
I am still unconvinced in Windows at least, that a thread cannot call MessageRequester()?
The thread is not creating a main window, only a subordinate, but modal(blocking) dialog that should be owned by the main window.
I am confused by that scenario anyway, since how can the OS display more than 1 modal dialog?
Which 1 is the leader?
Do you have an example code with 2 threads each calling a MessageRequester()?
EDIT: haha, you posted too fast!
I am still unconvinced in Windows at least, that a thread cannot call MessageRequester()?
The thread is not creating a main window, only a subordinate, but modal(blocking) dialog that should be owned by the main window.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: MessageRequester() in a thread allowed or not
The main window of the MessageRequerster is locked,
but two MessageReguester are opened when they are called in the thread.
I can't say how stable this works on Windows. But it is not advantageous if several requesters are started.
Under Linux and MacOS you are not allowed to start the requester from threads, because this leads to a crash...
but two MessageReguester are opened when they are called in the thread.
I can't say how stable this works on Windows. But it is not advantageous if several requesters are started.
Under Linux and MacOS you are not allowed to start the requester from threads, because this leads to a crash...
Code: Select all
;-TOP
; Example ThreadToGUI SendEvent
IncludeFile "Modul_ThreadToGUI.pb"
Enumeration
#Window
EndEnumeration
;- Test
;- Constants
Enumeration #PB_Event_FirstCustomValue
#My_Event_GUI
#My_Event_Question
EndEnumeration
Procedure thWork(ID)
Protected result, cnt
Debug "Init Thread"
;MySemaphore = CreateSemaphore()
Repeat
Delay(500)
cnt + 1
;result = MessageRequester("Questions", "Continue " + ID, #PB_MessageRequester_YesNoCancel)
;result = ThreadToGUI::SendEvent(#My_Event_Question, 0, 0, 0, ID * 1000 + cnt)
result = ThreadToGUI::DoMessageRequester("Questions", "Continue " + ID, #PB_MessageRequester_YesNoCancel)
Select result
Case #PB_MessageRequester_Yes
Debug "Result Yes"
Case #PB_MessageRequester_No
Debug "Result No"
Case #PB_MessageRequester_Cancel
Debug "Result Cancel"
EndSelect
Until result = #PB_MessageRequester_Cancel
If MySemaphore
FreeSemaphore(MySemaphore)
EndIf
Debug "Exit Thread"
EndProcedure
Global MyEvent
If OpenWindow(#Window, 0, 0, 800, 600, "Example SendEvent", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
UseModule ThreadToGUI
hThread = CreateThread(@thWork(), 1)
hThread2 = CreateThread(@thWork(), 2)
BindEventGUI(#My_Event_GUI)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
exit = 1
Case #PB_Event_Gadget
Case #My_Event_Question
MyEvent = EventData()
Value = SendEventData(MyEvent)
Debug "Incomming Message from thread. Data: " + Str(Value)
result = MessageRequester("Questions", "Continue " + Value, #PB_MessageRequester_YesNoCancel)
DispatchEvent(MyEvent, result)
EndSelect
Until exit
If IsThread(hThread)
Debug "Kill Thread"
KillThread(hThread)
EndIf
If IsThread(hThread2)
Debug "Kill Thread 2"
KillThread(hThread2)
EndIf
EndIf
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