Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TidHTTPServer and Orphaned Connection Threads
#4
(06-30-2019, 10:38 PM)takyon_dg Wrote: As for the XML object, my understanding is it doesn't need to be released as it's type IXMLDocument.

Yes, it does need to be released (all COM interfaces do) before COM is uninitialized.  Either by letting the variable go out of scope sooner rather than later (ie, moving your XML processing logic into another function that is called after CoInitialize() and before CoUninitialize()), or by explicitly setting the variable to nil.  On Windows, IXMLDocument internally uses the MSXML library by default, and MSXML is based on COM objects.

(06-30-2019, 10:38 PM)takyon_dg Wrote: Everything I've seen online about using it suggests it will get freed when it goes out of scope.

Yes, but in your code example, that happens AFTER CoUninitialize() is called, which is a bad thing.

(06-30-2019, 10:38 PM)takyon_dg Wrote: I figured the most I could do is set Active to false which should be triggered via it's try-finally before the CoInit/CoUnInit are.

Deactivating the document is a different operation then releasing the document.

(06-30-2019, 10:38 PM)takyon_dg Wrote: Are you saying I should be setting XMLDoc := nil; after XMLDoc.Active := False?

Yes.  As well as any other IXML... interface variables that are still in scope when CoUninitialize() is called.

(06-30-2019, 10:38 PM)takyon_dg Wrote: I'm curious why you suggest using the scheduler. Is it simply better practice or do you believe it is related to my reported issue(s).

My suggestion has nothing to do with your particular issue.  It is just an enhancement, given how many connections you are processing. Indy TCP servers use 1 thread per TCP connection.  Thread creation and destruction are expensive tasks for an OS, so you might consider using TIdSchedulerOfThreadPool to pool and reuse connection threads over time to lessen the overhead.  By default, Indy TCP servers use TIdSchedulerOfThreadDefault, which creates a new thread on each new TCP connection, and terminates the thread on disconnect.

COM should only be initialized once per thread, so it makes sense to hook into the thread startup/shutdown logic to (un)initialize COM one time per thread.  Even if you don't use thread pooling, I would still recommend this approach, because it moves the Co(Un)Initialize() calls higher up on the call stack, outside of your OnCommandGet event handler, ensuring that COM is initialized before OnCommandGet is called, and is uninitialized after OnCommandGet exits and all of your local IXML... variables go out of scope.

(06-30-2019, 10:38 PM)takyon_dg Wrote: And yes, my next step was to upgrade Indy, though I'm cautious as I can't find a changelog ... is there not a itemized changelog somewhere?

No, there is not.  You would have to look at the individual SVN/GIT checkin comments.

Although, Indy's website does contain a blog that has a Changelog category, which I post to whenever I make noteworthy changes to Indy that may affect user code and require explanation. But I don't post to it for smaller changes that only affect Indy internally.

Reply


Messages In This Thread
RE: TidHTTPServer and Orphaned Connection Threads - by rlebeau - 07-02-2019, 08:56 PM

Forum Jump:


Users browsing this thread: 2 Guest(s)