It is currently Sat Jul 20, 2019 12:50 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: MessageRequester() in a thread allowed or not
PostPosted: Wed Feb 27, 2013 9:25 pm 
Offline
Addict
Addict

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 4256
Location: Germany
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


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Wed Feb 27, 2013 9:34 pm 
Offline
Always Here
Always Here
User avatar

Joined: Thu Jun 24, 2004 2:44 pm
Posts: 5754
Location: Berlin - Germany
Never use a Requester in a thread!

_________________
PureBasic 5.70 | SpiderBasic 2.21 | Windows 10 Pro (x64) | Linux Mint 19.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Wed Feb 27, 2013 9:56 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Dec 03, 2011 5:54 pm
Posts: 736
Location: Oldenburg (Germany)
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


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Wed Feb 27, 2013 10:09 pm 
Offline
Addict
Addict

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 4256
Location: Germany
Ok, ok,

I change everything to:
Code:
PostEvent(#EventShowMessageRequester, #MainWindow, 0, 0, @Text$)
WaitSemaphore(MessageRequesterSemaphore)


Thank you very much, tomorrow I can try it.

Bernd


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Wed Feb 27, 2013 10:19 pm 
Offline
Always Here
Always Here
User avatar

Joined: Thu Jun 24, 2004 2:44 pm
Posts: 5754
Location: Berlin - Germany
I have made a small example for you, but you are so fast :wink:
Code:
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


Greetings - Thomas

_________________
PureBasic 5.70 | SpiderBasic 2.21 | Windows 10 Pro (x64) | Linux Mint 19.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Tue Jan 15, 2019 1:06 am 
Offline
Addict
Addict
User avatar

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 2967
Location: Boston, MA
infratec wrote:
Ok, ok,
I change everything to:
Code:
PostEvent(#EventShowMessageRequester, #MainWindow, 0, 0, @Text$)
WaitSemaphore(MessageRequesterSemaphore)
Thank you very much, tomorrow I can try it.
Bernd
Hi, I just noticed your posting on calling MessageRequester()'s from a thread.
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. :oops:

_________________
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Tue Jan 15, 2019 10:50 pm 
Offline
Addict
Addict
User avatar

Joined: Fri May 12, 2006 6:51 pm
Posts: 1761
Location: Germany
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
Code:
;-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 / OOP-BaseClassDispatch / Event-Designer
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Tue Jan 15, 2019 11:32 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 2967
Location: Boston, MA
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.

_________________
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum


Top
 Profile  
Reply with quote  
 Post subject: Re: MessageRequester() in a thread allowed or not
PostPosted: Wed Jan 16, 2019 1:10 pm 
Offline
Addict
Addict
User avatar

Joined: Fri May 12, 2006 6:51 pm
Posts: 1761
Location: Germany
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...
Code:
;-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 / OOP-BaseClassDispatch / Event-Designer
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye