* harbour/include/hbstack.h
* harbour/include/hbgtcore.h
* harbour/include/hbthread.h
* harbour/include/hbapigt.h
* harbour/source/vm/estack.c
* harbour/source/vm/hvm.c
* harbour/source/vm/thread.c
* harbour/source/rtl/hbgtcore.c
+ added support for optional allocating independent console window by
each thread. By default new thread inherits console Window from
parent thread. But each thread can allocate its own console window
by calling hb_gtReload( <cGtName> ) function, f.e. by:
hb_gtReload( hb_gtVersion() )
If GT driver supports such functionality then new it will allocate
new console windows.
Each console window has reference counter which is increased when
new thread starts and decreased when hb_gtReload() is executed or
thread terminates. When counter reach zero give console window is
destroyed.
* harbour/source/rtl/gtwvt/gtwvt.c
! use SendNotifyMessage() instead of SendMessage() to not block
threads which inherited GT from parent thread. Why non of MS-Win
users reported this problem?
+ added reference counter to window class for multi GT support
+ harbour/tests/mt/mttest10.prg
+ added demonstration/test code for using independent console window
in different threads. It needs GT driver which supports such
functionality, f.e GTXWC in *nixes or GTWVT in MS-Windows
* harbour/tests/mt/mttest09.prg
! fixed typo in comment
70 lines
1.7 KiB
Plaintext
70 lines
1.7 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* demonstration/test code for using the same work area in different
|
|
* threads. Please note that this program also works when compiled
|
|
* without thread support.
|
|
*
|
|
* Copyright 2008 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
*/
|
|
|
|
STATIC s_mainThreadID
|
|
|
|
proc main()
|
|
field F1
|
|
local thID, bResult
|
|
|
|
s_mainThreadID := hb_threadSelf()
|
|
/* create table */
|
|
dbCreate("_tst",{{"F1","C",1,0}})
|
|
use _tst
|
|
while lastRec() < 10000
|
|
dbAppend()
|
|
F1 := chr( recno() )
|
|
enddo
|
|
|
|
? "main thread ID:", s_mainThreadID
|
|
thID := hb_threadStart( @thFunc() )
|
|
? "current thread ID:", thID
|
|
? "work area in use, used() =>", used(), alias()
|
|
WAIT "Press a key to detach work area"
|
|
hb_dbDetach( , {|| countRecords( {|| F1 == "A" } ) } )
|
|
? "work area detached, used() =>", used(), alias()
|
|
? "we will make some other things now..."
|
|
hb_idleSleep( 1 )
|
|
? "let's check the result"
|
|
? "request for work area"
|
|
hb_dbRequest( , , @bResult, .T. )
|
|
? "work area atached, used() =>", used(), alias()
|
|
? "query result:", eval( bResult )
|
|
close
|
|
dbDrop("_tst")
|
|
return
|
|
|
|
proc thFunc()
|
|
local bQuery, xResult
|
|
|
|
if hb_dbRequest( , , @bQuery, .T. )
|
|
xResult := Eval( bQuery )
|
|
dbRelease( , {|| xResult } )
|
|
endif
|
|
return
|
|
|
|
static func countRecords( bFor )
|
|
local nCount := 0
|
|
dbGoTop()
|
|
while ! eof()
|
|
if eval( bFor )
|
|
nCount ++
|
|
endif
|
|
dbSkip()
|
|
enddo
|
|
? "!!! JOB DONE !!!" + iif( hb_threadSelf() == s_mainThreadID, ;
|
|
" (by main thread)", " (by child thread)" )
|
|
return nCount
|