This document bases on information and testing done with IIS 1.0. We have not re-tried it with later versions. However, we feel very comfortable with the information contained herein and think that it still is correct.
There is just one exception: if you create an application in MMC under IIS 4.0, your ISAPI extension is run in a separate process space (as far as we know under MTS control). In this case, you obviously do not run in the process space of IIS (that's why it is called process isolation). As far as your extension is concerned, that should make no big difference.
When we first started developing isapi apps, things were first very clear to us. However, as soon as we hit the field of "real" IIS application with multiple concurrent requests and multiple extensions being loaded, things became quite more complicated. All of a sudden, some things looked really confusing.
We found that the key to order this things at get a productive application out of our coding is understanding what IIS really does and how an extension is executed. This is what we call the ISAPI Execution Environmen and this is what this document is all about.
We hope it will save you some valuable time when first starting isapi development.
In order to allow easy offline storage and printout, we have created just this single, relativly large document. People with slow links and/or not-so-current browsers, please forgive us. We think it is the best compromise available.
If you find anything to add, correct or otherwise change in this document, please do not hesitate to
Found an error or have a suggestion? Let us know and we'll review it.
Things to watch for
Memory Protection
Being part of IIS process space, isapi apps have full access to all of this space. Thus it is not only possible to read data at any location of the process space, your app can also write at any writable memory location. This includes locations outside of your isapi app, including some that are vital for IIS' health. An isapi app can thus easily crash IIS and stop it from running. Keep this in mind when debugging you applications. They deserve very special attention, as your application's error can cause some other applications - possibly some highly important ones - to crash instantly (well, looks a bit like being back in good old Win16 days...).
Multithreading
Isapi apps get called by multiple IIS threads concurrently (given concurrent HTTP requests). Thus your coding needs to be threadsafe. You have to apply special threadsafe coding technologies in order to get things running well.
In contrast to some of your other multithreaded applications, however, you do not have control over the "main" thread of your program. First let's explain what I mean with main thread. This is the thread that initially gets control, initializes global data structures and the "multithreading". With multithreading initialization I mean the creation of synchronization objects and subordinate threads (as well as, of course, all data that is used by your application to control useful multithreading work).
One example of this might be the allocation of an ODBC environment handle. According to ODBC SDK documentation such a handle should exist only once in a process space. The resulting handle itself is threadsafe and can be used by multiple threads concurrently. Thus, in your regular application, you might create the environment handle inside your main thread at startup, than go to your regular work (which involves the multithreading) and - at process termination time - close the handle. You'll never run into trouble, as your application has total control over the usage of its handle and who's using it.
With IIS, however, things are quite different. Here the main thread is IIS. IIS unfortunately doesn't know about your need of an ODBC environment handle. Thus its main thread doesn't allocate one (at least we don't know about this) and in turn can not pass it down to you. So your only option is to allocate the handle at DLL startup (using DllMain) and free it at unload time. This works pretty well as long as there is only one isapi app doing ODBC operations. But what about a second one concurrently being loaded? Doesn't this one also need to get and free a handle? Sure it does. And - voila - here we have two handles inside one process space. As far as I know, you have absolutely no chance to get around this (as you do not control the main thread).
Giving this example, there is one question: why do real-life IIS installations not crash? To be honest - I don't know. Most isapi apps do exactly what I have described. Without ever crashing. I have run quite a lot of tests with a large number of concurrently allocated ODBC environment handles - and it never crashed. To me, it looks as if only documentation is in error and this operations seems to be pretty OK.
The above example is an extreme side of IIS' multithreading topic: it's not really all that bad, but be warned about what you are doing and what implications it has. Please note that there may be other scenarios like the "ODBC environment handle scenario" described above. Also keep in mind that your perfectly well coded isapi app might run into trouble if it meets a not-so-well coded other app in the same server.
And if you have a look at just your application: be sure to use only threadsafe technologies and coding. Be very skeptic about third party software (MFC included). Dig into the topic to be sure that it is really threadsafe. Check it with multiple concurrent executions at the beginning of your development project.
Inside your own coding, be although sure to code threadsafe. You won't need special coding technologies just to get your isapi app up and running. If there is no need to access "global" objects inside your app, you probably will never need any special coding. However, if you use e.g. global data structures you should protect them from improper usage by your threads. If you need to do this, use synchronization structures like critical sections. Make sure that no more than one thread can access such a critical object at a given time. By the way: this is they way to get around with non-threadsafe third party coding: if you *really* have to use it, put it in a critical section and be happy (although this has some performance implications). This is what Microsoft did in its OLEISAPI sample coding (for NT w/o DCOM).
If you have special interest in IIS' multithreading issues, you might want to download our MFC classes
We (and others as well) had some bad experiences with MFC classes (version 4.x!). Before you use any class, be sure to check if it can successfully be used inside an isapi app. We know that at least the following is dangerous:
Disclaimer
The information contained in this document is to the best of our knowledge. However, we do not guarantee its accuracy. Use the information contained herein at your sole risk.
Rainer Gerhards works for
Suggest a Correction
The ISAPI Execution Environment
1 views
Comments (0)
Please sign in to leave a comment.





No comments yet. Be the first to comment!