how to react when calling from hb_thread

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

Post Reply
User avatar
AUGE_OHR
Posts: 2060
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

how to react when calling from hb_thread

Post by AUGE_OHR »

hi,

i try to implement USB_Detect() but have some Problem

Code: Select all

   aThread[ 1 ] := hb_threadStart(HB_THREAD_INHERIT_PUBLIC , @Wait4Action() )
   aThread[ 2 ] := hb_threadStart(HB_THREAD_INHERIT_PUBLIC , @DoNothing() )

   CREATE EVENT PROCNAME USB_Detect() HWND Win_1.HANDLE STOREINDEX nIndex
USB_Detect() get Windows Event

Code: Select all

FUNCTION USB_Detect()
LOCAL nHWnd    := EventHWND()
LOCAL nMsg     := EventMSG()
LOCAL nWParam  := EventWPARAM()
LOCAL nLParam  := EventLPARAM()
DO CASE
   CASE nMsg == WM_DEVICECHANGE
   DO CASE
      CASE nWParam == DBT_DEVICEARRIVAL
         lPublic := .T.
      CASE nWParam == DBT_DEVICEREMOVECOMPLETE
         lPublic := .T.      
      End CASE
End Case
RETURN cDevice
Wait4Action() is running in hb_thread and wait for "Action"

Code: Select all

STATIC FUNCTION Wait4Action()
DO While !lExit
      IF lPublic = .T.
         lPublic = .F.
         cAction := aAction[1]
         cDevice := aAction[2]
         nInfo   := aAction[3]
         IF !EMPTY(cAction) .AND. !EMPTY(cDevice)
             cText := cAction + " " + cDevice + CRLF
             Msginfo(cText,STR(nInfo))
         ENDIF
         aAction := { "", "","" }
         FillCombo(.T.)          // this is the Way to crash App
      ENDIF
EndDo
RETURN nil
Problem :
a.) it work on Win_1.HANDLE but on Form are many Controls so if Mouse Cursor is not on Win_1 -> nothing happens :(
b.) as i´m in hb_thread i can not call Controls this Way in FillCombo()

Code: Select all

   Domethod( "WinLeft" , "ComboLeft" , "DeleteAllItems" )
Control: ComboLeft Of WinLeft Not defined. Program Terminated
Called from DOMETHOD(9090)
Called from FILLCOMBO(872)
Called from WAIT4ACTION(812)
include Main Win_1

Code: Select all

   Domethod( "Win_1", "WinLeft" , "ComboLeft" , "DeleteAllItems" )
Control: WinLeft Of Win_1 Not defined. Program Terminated
Called from DOMETHOD(9240)
Called from FILLCOMBO(872)
Called from WAIT4ACTION(812)
Wait4Action is running in Thread but i have no Access to Form Win_1 and it´s Controls :shock:

so what do i miss in harbour / HMG Thread Concept :idea:
please give me a hint.

p.s. have a Version with Mutex but same Problem
have fun
Jimmy
User avatar
AUGE_OHR
Posts: 2060
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

Re: how to react when calling from hb_thread

Post by AUGE_OHR »

i try my Question again.

the Sample is c:\hmg.3.4.4\SAMPLES\MultiThread\MT_GridIncrementalSearch\MT_GridIncrementalSearch.prg
"// Multi-Thread version of Grid Incremental Search demo ( without INHERIT PUBLIC vars ), by Dr. Claudio Soto, March 2017
// NOTE: this is a not convential use of thread, because this way create one new "instance" of HMG for each thread
// see note in declare THREAD STATIC vars in the function Proc_GridSearchString()"
it talk about "new instance" but i´m not sure what it mean in harbour / HMG :idea:

as i know PUBLIC are "visible" in Thread and a HMG Form is PUBLIC, right :?:
so i wonder why i fail to call "Main" from "Thread" when they are PUBLIC.

on other side "that" Sample use Thread and can access Main.Grid ...
can someone enlighten me what i miss :?:
have fun
Jimmy
User avatar
AUGE_OHR
Posts: 2060
Joined: Sun Aug 25, 2019 3:12 pm
DBs Used: DBF, PostgreSQL, MySQL, SQLite
Location: Hamburg, Germany

Re: how to react when calling from hb_thread

Post by AUGE_OHR »

hi

i have read more about hb_threadStart() and begin to understand about PUBLIC / PRIVATE which is different to Xbase++

harbour default can have "own" PUBLIC / PRIVATE for each Thread so they are not "visible" in other Thread like Field-Wide STATIC
to access a Form or Control in Main "from" Thread i need HB_THREAD_INHERIT_PUBLIC to make PUBLIC "visible" in Thread

---

i can use hb_threadStart() to start start Thread. after a while Thread might be "ready" or still "active"

Question : how to "detect" if Thread is "ready" or "active" :idea:

when "ready" ... what to do :?: hb_threadDetach() ... but ""when" :idea:
have fun
Jimmy
User avatar
mol
Posts: 3718
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Contact:

Re: how to react when calling from hb_thread

Post by mol »

Hi!
I don't want to create new topic, but I want to ask if it's the way to pass some parameters to the thread?
User avatar
vagblad
Posts: 160
Joined: Tue Jun 18, 2013 12:18 pm
DBs Used: MySQL,DBF
Location: Thessaloniki, Greece

Re: how to react when calling from hb_thread

Post by vagblad »

mol wrote: Wed Oct 13, 2021 2:24 pm Hi!
I don't want to create new topic, but I want to ask if it's the way to pass some parameters to the thread?
nThread := hb_threadStart(HB_THREAD_INHERIT_PUBLIC, @FunctionName(), Parameter1, Parameter2, Parametern )

Thats how i do it. Calling the Function first and then the required parameters in succession.
AUGE_OHR wrote: Mon Feb 10, 2020 9:48 am
i can use hb_threadStart() to start start Thread. after a while Thread might be "ready" or still "active"

Question : how to "detect" if Thread is "ready" or "active" :idea:

when "ready" ... what to do :?: hb_threadDetach() ... but ""when" :idea:
Jimmy the way i do it is this:

I declare a Public Array in MAIN thread(the actual program)

Code: Select all

Public aThreads := {}
Now when i create a new thread i do this :

Code: Select all

nThread := hb_threadStart(HB_THREAD_INHERIT_PUBLIC, @NewFunction() )
AAdd(aThreads, { nThread, 1 } // i add the thread handle and 1 as state which for me it means the thread is still running

FUNCTION NewFunction()
Local nHandle

//the code i need this function to do
//blah blah blah

//code is finished, now i need to "inform" the main thread that this thread is done
nHandle := hb_threadSelf()
For i := 1 to len(aThreads)
	If aThreads[i][1] == nHandle
		aThreads[i][2] := 0
	EndIf
Next i

//Now the thread array has been updated with the new status which is 0, which for me it means the specific thread has stopped running
In the Main program i setup a timer with a function which only does this thing

Code: Select all

FUNCTION CheckThreads()
Local i := 0

For i := 1 to len(aThreads)
	If aThreads[i][2] == 0 //in case the thread is done
		Hb_ThreadQuitRequest(aThreads[i][1]) //Just to be sure the thread ends.
	Else
		//Do here whatever you need in case the thread is still active	
	EndIf
Next i		
i hope it helps. i know it may not be the best way of doing it but thats how i do it at the moment.
Vagelis Prodromidis
Email: vagblad@gmail.com, Skype: vagblad
Post Reply