* harbour/include/hbapi.h
* harbour/source/vm/arrays.c
+ added hb_arrayGetPtrGC(), hb_arrayGetSymbol(), hb_arraySetSymbol()
* harbour/include/hbapi.h
* harbour/source/vm/dynsym.c
+ added hb_dynsymProtectEval(). Works like hb_dynsymEval() but
keeps dynamic symbol table locked during whole execution.
It's faster then hb_dynsymEval() but user function may not
access dynamic symbol tbale to not cause recursive locks
+ added protection against possible dynamic symbol table resizing
during hb_dynsymEval() by other threads.
* harbour/include/hbapi.h
* harbour/source/vm/memvars.c
+ added hb_memvarSaveInArray( int iScope, BOOL fCopy ) and
hb_memvarRestoreFromArray( PHB_ITEM pArray )
% use hb_dynsymProtectEval() in places where it's safe
* harbour/include/Makefile
+ harbour/include/hbthread.ch
+ added header file with thread constant definitions:
HB_THREAD_INHERIT_PUBLIC
HB_THREAD_INHERIT_PRIVATE
HB_THREAD_INHERIT_MEMVARS
HB_THREAD_MEMVARS_COPY
* harbour/include/hbthread.h
* harbour/source/vm/hvm.c
* harbour/source/vm/thread.c
+ added support for inheriting visible memvars from current
thread when new thread is created. Memvars in child thread
can be shared with parrent or they can be copied. See HB_THREAD_*
attributes defined in hbthread.ch, f.e.:
hb_threadStart( HB_THREAD_INHERIT_PUBLIC, @thFunc() )
or:
hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_MEMVARS + ;
HB_THREAD_MEMVARS_COPY ), ;
@thFunc() )
Please note that when child thread creates new PUBLIC variable
which didn't existed when thread was started then it's visible
only for this thread and optionally for its child threads but
not for parent thread.
Please also remember that write access to shared memvars have
to be protected by users.
+ harbour/tests/mt/mttest08.prg
+ added test code for thread memvars inheritance
138 lines
2.8 KiB
Plaintext
138 lines
2.8 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* demonstration/test code for using memvar variables sharing and
|
|
* copping
|
|
*
|
|
* Copyright 2008 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
*/
|
|
|
|
#include "hbthread.ch"
|
|
|
|
memvar pub1, pub2
|
|
memvar prv1, prv2
|
|
|
|
proc main()
|
|
|
|
? Version()
|
|
? "Main start"
|
|
|
|
public pub1, pub2
|
|
private prv1, prv2
|
|
|
|
?
|
|
? "Do not inherit memvars."
|
|
initVars()
|
|
? "main thread:"
|
|
testAllVars()
|
|
hb_threadJoin( hb_threadStart( @thFunc() ) )
|
|
? "main thread:"
|
|
testAllVars()
|
|
wait
|
|
|
|
?
|
|
? "Inherit copy of publics."
|
|
initVars()
|
|
? "main thread:"
|
|
testAllVars()
|
|
hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_PUBLIC, ;
|
|
HB_THREAD_MEMVARS_COPY ), ;
|
|
@thFunc() ) )
|
|
? "main thread:"
|
|
testAllVars()
|
|
wait
|
|
|
|
?
|
|
? "Inherit copy of privates."
|
|
initVars()
|
|
? "main thread:"
|
|
testAllVars()
|
|
hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_PRIVATE, ;
|
|
HB_THREAD_MEMVARS_COPY ), ;
|
|
@thFunc() ) )
|
|
? "main thread:"
|
|
testAllVars()
|
|
wait
|
|
|
|
?
|
|
? "Inherit copy of publics and privates."
|
|
initVars()
|
|
? "main thread:"
|
|
testAllVars()
|
|
hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_MEMVARS, ;
|
|
HB_THREAD_MEMVARS_COPY ), ;
|
|
@thFunc() ) )
|
|
? "main thread:"
|
|
testAllVars()
|
|
wait
|
|
|
|
?
|
|
? "Share publics with child threads."
|
|
initVars()
|
|
? "main thread:"
|
|
testAllVars()
|
|
hb_threadJoin( hb_threadStart( HB_THREAD_INHERIT_PUBLIC, @thFunc() ) )
|
|
? "main thread:"
|
|
testAllVars()
|
|
wait
|
|
|
|
?
|
|
? "Share privates with child threads."
|
|
initVars()
|
|
? "main thread:"
|
|
testAllVars()
|
|
hb_threadJoin( hb_threadStart( HB_THREAD_INHERIT_PRIVATE, @thFunc() ) )
|
|
? "main thread:"
|
|
testAllVars()
|
|
wait
|
|
|
|
?
|
|
? "Share publics and privates with child threads."
|
|
initVars()
|
|
? "main thread:"
|
|
testAllVars()
|
|
hb_threadJoin( hb_threadStart( HB_THREAD_INHERIT_MEMVARS, @thFunc() ) )
|
|
? "main thread:"
|
|
testAllVars()
|
|
wait
|
|
|
|
return
|
|
|
|
static proc initVars()
|
|
pub1 := "main:public1"
|
|
pub2 := "main:public2"
|
|
prv1 := "main:private1"
|
|
prv2 := "main:private2"
|
|
return
|
|
|
|
static proc testAllVars()
|
|
test_var( "PUB1" )
|
|
test_var( "PUB2" )
|
|
test_var( "PRV1" )
|
|
test_var( "PRV2" )
|
|
return
|
|
|
|
static proc test_var( cVarName )
|
|
? " " + cVarName + ":", type( cVarName )
|
|
if ! type( cVarName ) == "U"
|
|
?? " ->", &cVarName
|
|
endif
|
|
return
|
|
|
|
static proc thFunc()
|
|
? "child thread:"
|
|
testAllVars()
|
|
? "assign..."
|
|
pub1 := "thread:public1"
|
|
pub2 := "thread:public2"
|
|
prv1 := "thread:private1"
|
|
prv2 := "thread:private2"
|
|
? "child thread:"
|
|
testAllVars()
|
|
return
|