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 _______________________________________________ Harbour mailing list Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour