Re:Is this a bug in the TIdHTTPServer or am I doing something wrong?
Quote
Arthuro wrote:
> Care to tell us how you fixed it?
No.
...well, seeing as it's yule and everything...
The problem is that the PurgeStaleSessions method sets "purged" entries
to nil instead of deleting the from the sessionlist. Somewhere else the
sessionlist class iterates through all the entries calling various
methods on the objects in this list... Thus, instead of setting the
purged entry to nil I simply deleted it. There is no logic in place to
reuse nil'ed entries, hence I took the "easy" way out for now, and any
optimizations will have to be carefully grafted on after we've finished
this particular class (I suspect there's still one or two things left
unimplemented -- I just started looking at this thing...).
Oh, I also ripped out the batch logic from PurgeStaleSessions. IMO it
makes little sense to unlock a TThreadList only to lock it nanoseconds
later. Other threads have likely entered into kernel code at this point,
and won't have a chance to obtain a lock in this extremely small
timeframe (unless LeaveCriticalSection also calls sleep() or similar).
Again, any optimization at this point should be carefully executed and
not put in at random.
My suggestion (to reduce the time spent Purging) is to introduce a
PurgeInProgress state variable so that RemoveSession knows that the
session is being purged and thus not attempt to lock the list in order
to remove the session. Thus PurgeStaleSessions would simply mark the
session as being purged, move the entry to a separate list and free the
entries after it has unlocked the sessionlist (now empty of sessions
being purged). That's the gist of it anyway.
However, at this point I haven't had time to consider what happens if
some external code tries to free a session forcibly at the same time as
PurgeStaleSessions is being executed. I fear that the destructor could
be executed twice, but this is a concern that applies to every object in
a multithreaded application, and thus its the component user's
responsibility to not go 'overboard' when juggling around with the same
objects from separate threads. If this is a valid pre-condition, then
some of the original PurgeStaleSession code doesn't make a whole lot of
sense. (that is: apart from the AVs it still didn't make a whole lot of
sense)
I'll post a more lengthy explanation as more information becomes
available.
E-Mail me if you have the time and inclination to betatest the new
IdHTTPServer.pas unit.
--
Rune