[Harbour] hblognet, inet and threads
Przemyslaw Czerpak
druzus at acn.waw.pl
Sun Dec 7 12:07:06 EST 2008
On Fri, 05 Dec 2008, Francesco Saverio Giudice wrote:
Hi Francesco,
> In meanwhile I have tried and my code seems to work correctly: speed is
> impressive and in MT mode I'm not loosing UDP packets as I did in ST
In UDP packets can be lost by definition and it's programmer job
to detect it and repeat messages if necessary.
Here MT mode can help only indirectly by reducing some time conditions
but it does not eliminate the problem.
> version. Now I'm trying to make a better version more MT oriented.
> And, I didn't believe it, also background tasks works in MT version without
> problems (as I have used them in ST version for console add-ons) or at last
> it seems to be working.
The default ST code should have additional protection for setting/restoring
tasks or the task list should be local to thread.
Using MT you can also create alternative version of background tasks
without modifing main HVM loop or other HVM structures.
You can simply create separate thread which will execute your tasks.
F.e. sth like:
static s_aTasks := {}
static s_nCounter := 0
static s_nLastTime := 0
static s_lStop := .t.
static s_onceControl
static s_mutex
static function hb_backgroundThread()
local n, nTime
while !s_lStop
hb_mutexLock( s_mutex )
nTime := s_nLastTime
s_nLastTime := seconds()
nTime -= s_nLastTime
if nTime < 0
nTime += 24 * 60 * 60
endif
nTime *= 1000
for n := 1 to s_nCounter
if s_aTasks[ n, 4 ] .and. s_aTasks[ n, 3 ] <= nTime
eval( s_aTasks[ n, 2 ] )
endif
next
hb_mutexUnlock( s_mutex )
hb_idleSleep( 0.01 )
enddo
return nil
function hb_backgroundInit()
if s_lStop
hb_threadOnce( @s_onceControl, {||
s_mutex := hb_mutexCreate()
hb_mutexLock( s_mutex )
s_lStop := .f.
hb_threadStart( @hb_backgroundThread() )
hb_mutexUnlock( s_mutex )
return nil
} )
endif
return nil
function hb_backgroundAdd( bAction, nMilliSec, lActive )
local nHandler
if !HB_ISNUMERIC( nMilliSec )
nMilliSec := 0
endif
if HB_ISLOGICAL( lActive )
lActive := .t.
endif
hb_backgroundInit()
hb_mutexLock( s_mutex )
aadd( s_aTasks, { nHandler := ++s_nCounter, bAction, nMilliSec, lActive } )
hb_mutexUnlock( s_mutex )
return nHandler
function hb_backgroundDel( nHandler )
local bAction, n
if HB_ISNUMERIC( nHandler )
hb_backgroundInit()
hb_mutexLock( s_mutex )
if ( n := ascan( s_aTasks, { |x| x[ 1 ] == nHandler } ) ) != 0
bAction := s_aTasks[ n, 2 ]
hb_adel( s_aTasks, 2, .t. )
endif
hb_mutexUnlock( s_mutex )
endif
return bAction
function hb_backgroundActive( nHandler, lActive )
local lOldActive := .f., n
if HB_ISNUMERIC( nHandler )
hb_backgroundInit()
hb_mutexLock( s_mutex )
if ( n := ascan( s_aTasks, { |x| x[ 1 ] == nHandler } ) ) != 0
lOldActive := s_aTasks[ n, 4 ]
if HB_ISLOGICAL( lActive )
s_aTasks[ n, 4 ] := lActive
endif
endif
hb_mutexUnlock( s_mutex )
endif
return lOldActive
function hb_backgroundTime( nHandler, nMilliSec )
local lOldMilliSec := .f., n
if HB_ISNUMERIC( nHandler )
hb_backgroundInit()
hb_mutexLock( s_mutex )
if ( n := ascan( s_aTasks, { |x| x[ 1 ] == nHandler } ) ) != 0
lOldMilliSec := s_aTasks[ n, 3 ]
if HB_ISNUMERIC( nMilliSec )
s_aTasks[ n, 3 ] := nMilliSec
endif
endif
hb_mutexUnlock( s_mutex )
endif
return lOldMilliSec
I haven't tested above code. I've just written it as an example.
best regards,
Przemek
More information about the Harbour
mailing list