Kevin, glad to help you out, thanks for the kind words.
Willy.
| Thanks, Willy. I wish I could have found such a fantastically clear
| explanation of this on the web. You've been a great help.
|
| Thanks
|
| Kevin
|
| | >
| >
| >
| > | > | OK. Thanks. So are you saying that IIS is creating the threads, not
the
| > | ASP.NET framework? If so, I'm confused, because aspnet_wp.exe is *not*
| > IIS
| > | and that's where I am seeing extra threads being created. Actually,
| > thinking
| > | about it a little, my confusion is even greater, because usually
| > | "extensions" to IIS are in the form of an ISAPI DLL, yet here is an
| > | *executable* getting run (somehow) by IIS. It's a side issue - but do
| > you
| > | know the process by which all this starts running?
| > |
| >
| > No, I'm talking about the "worker process" which is "aspnet_wp.exe" on
W2K
| > and XP (different name different architecture on W2K3).
| > The "worker process" is handling all "asp.net" requests and it's started
| > and
| > fed by the .NET ISAPI extension (aspnet_filter.dll), communication
between
| > IIS (actually the ISAPI filter) and the worker process goes via a named
| > pipe.
| >
| > | Anyway, regardless of why I'm not getting the THREAD_ATTACH/DETACH
| > | notifications, I still have a problem to solve, hence my next
| > question...
| > |
| > | If you wanted to use Thread-Local-Storage, then the absence of
| > THREAD_ATTACH
| > | notifications prevents you from initialising a "thread local storage
| > object"
| > | in advance. That's fine, because it can be solved just as easily with
| > "lazy
| > | instantiation" (eg. if p == null then instantiate the object).
| > |
| > | Unfortunately the reverse is not true in terms of cleaning up these
| > objects.
| > | Since there is no THREAD_DETACH notification, there is no logical
point
| > (as
| > | far as a .NET assembly is concerned) for cleaning up the thread's
thread
| > | local storage object. At the moment we are just letting it leak, until
| > we
| > | think of an idea.
| > |
| > | How dangerous the leak is I guess depends on whether IIS or ASP.NET
| > | terminates threads from the pool and then recreates them. In other
| > words,
| > | does the thread pool grow *and* shrink? Or does it only ever grow?
| > |
| > The thread pool grows until it reaches the maximum threads (25 per CPU
by
| > default but configurable), incomming requests are queued and picked up
by
| > a
| > free thread from the pool until the maximum number of threads is reached
| > and
| > all threads are busy, that's the point where requests may get delayed.
| > That
| > means that threads live as long as the application domain related to the
| > web
| > application.
| > Whenever the worker process detects an application failure (out-of
| > memory/stack, whatever) or a deadlock at the level of the thread pool,
it
| > will recycle the AD, that is, it unloads the AD which implicitely aborts
| > all
| > threads (and releases the TLS) and unloads all assemblies loaded into
this
| > AD, after that the worker recreate the AD for the application and waits
| > for
| > new requests to arrive.
| > So, that means that the threads are kept alive as long as the AD exists,
| > no
| > new threads are getting created, instead the existing threads are pulled
| > from the pool over and over again until the whole thing gets torned
down.
| > Note that the AD is also unloaded after a time-out period during which
no
| > new requests arrived.
| >
| > | If the thread pool does shrink as well, then over time our memory leak
| > could
| > | become a problem (although the object in question is only about 30
bytes
| > in
| > | size, so it will require a large amount of threads to start/stop
before
| > | having any discernible memory impact).
| > |
| >
| > If, you read the above (and I hope I made it clear), you'll understand
| > that
| > there is no issue (well I don't see any) with TLS in asp.net.
| >
| > Willy.
| >
| >
| > | So do you happen to have a plan of attack for handling this problem?
| > |
| > | Thanks
| > |
| > | Kevin
| > |
| > | | > | > No, the CLR doesn't use DisableThreadLibraryCalls.
| > | > What's happening is, that the worker process uses a pool of threads,
| > when
| > | > the "very first" web request arrives, the poolmanager creates a
| > minimum
| > of
| > | > pooled threads (default is 3 for IIS5) and pulls a thread from the
| > pool
| > to
| > | > handle the request. Your request handler loads the DLL (delay
loaded)
| > as
| > a
| > | > result of a call into your dll, but that's is after the minimum pool
| > of
| > | > threads are created, so you don't see any DLL_THREAD_ATTACH. When
the
| > | > request finishes, the thread returns to the pool where it wait's to
| > handle
| > | > up-comming requests. That means that you won't see any
| > DLL_THREAD_ATTACH
| > | > as
| > | > long as there are free threads in the pool.
| > | >
| > | > Willy.
| > | >
| > | > | > | > | I'm also suspecting that the CLR is using
DisableThreadLibraryCalls
| > | > since
| > | > I
| > | > | know for a fact that the aspnet_wp.exe creates additional threads
| > and
| > I
| > | > | don't see any notifications.
| > | > |
| > | > | Kevin
| > | > |
| > message
| > | > | | > | > | > | > | > | >> The most confusing thing is understanding how aspnet_wp.exe can
| > | > create
| > | > a
| > | > | >> new thread but those threads don't produce corresponding
| > | > THREAD_ATTACH'es
| > | > | >> in my assembly.
| > | > | >
| > | > | > You might want to post in an ASP.Net group.
| > | > | >
| > | > | > But a possible explanation is that ASP.Net creates a thread pool
| > in
| > | > | > advance of loading your assembly. Then it assigns a thread as
| > | > necessary
| > | > | > from the pool to service the request which passes through your
| > | > assembly.
| > | > | > If that's the case, you won't see the thread attach
notification.
| > | > | >
| > | > | > Regards,
| > | > | > Will
| > | > | >
| > | > | >
| > | > | >
| > | > |
| > | > |
| > | >
| > | >
| > |
| > |
| >
| >
|
|