On Thu, 05 Mar 2009, Przemyslaw Czerpak wrote:

Hi,

> Replacing privates with statics is rather bad idea. Privates are
> automatically dealocated when they are out of scope. statics exist
> for the whole application life so when they are not longer necessary
> and you want to clear the items inside you have to make it yourself.
> Of course it depends on application context. But to clarify before
> other people begin to change his code. There is nothing technically
> wrong in using memvars (private and publics). If you want and like
> them then use them. For sure it will be many times faster and consume
> less resources then emulating memvar behavior at .prg level using
> statics or locals what IMHO is technical nonsense.

I'm really sorry. I was wrong.
PRIVATE declaration can be used in any place of code and it was
beyond my and other [x]Harbour developers imagination ;-) that user
may want to create code like:
   while .t.
      private var := <something>
      ...
   enddo
so each private declaration creates new private variable which is
pushed on private stack and is cleared on function exit. I'll add
RT protection against such code to HVM (check if function already
declared private with given name and ignore declaration in such
case) but meanwhile please move private declaration out of the loop.
   PRIVATE _SERVER, _GET, _POST, _COOKIE, _SESSION
   PRIVATE _REQUEST, _HTTP_REQUEST, m_cPost

and inside the loop only assign these values:

   _SERVER := HB_IHASH(); _GET := HB_IHASH(); _POST := HB_IHASH()
   _COOKIE := HB_IHASH(); _SESSION := HB_IHASH()
   _REQUEST := HB_IHASH(); _HTTP_REQUEST := HB_IHASH()
   m_cPost := NIL

and memory "leaks" will gone ;-)

BTW:
      hb_DispOutAt( 10, 40, "memory: " + hb_ntos( memory( HB_MEM_USED ) ) )
in show application info should help you in watching memory consumption
when you link your application with fmstat module (-fmstat hbmk2 parameter).

Please also check the access to some variables, f.e. s_aRunningThreads
seems to be unprotected at all and is resized by different threads.
In code like:

   FOR n := 1 TO s_nStartThreads
       pThread := hb_threadStart( @ProcessConnection(), @nThreadID )
       AADD( s_aRunningThreads, { pThread, nThreadID } )
   NEXT

you have classic race condition. nThreadID may not be assigned by
the new thread before you add it to s_aRunningThreads.
BTW why do you need it and do not use pThread only? f.e.:
      AADD( s_aRunningThreads, pThread )
You can extract thread number at any moment using:
      hb_threadId( [ <pThID> ] ) -> <nThNo>
but you can also use directly <pThID> in == or = comparisons or in
ascan().

best regards,
Przemek
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to