ISAPI Programming Tips

HomeOverviewHow Do I

It is important to remember that your ISAPI application is running in the context of a service on NT. This means your code must be thread safe, it must be reentrant, and it has no user interface on the server.

Server Extension (ISA) Memory Management

If you want to allocate data on a per-call basis, you must use the data carefully within a synchronization object. The example below demonstrates overriding the HttpExtensionProc member function and using a critical section to associate per-call data with the ConnID. The base class is then called to process the request. Any member functions that use the data must protect it with a synchronization object. Upon return from HttpExtensionProc processing, the data for that ConnID is freed.

// in your .H file, declare variables and override HttpExtensionProc
class CISAPIWizExtension : public CHttpServer
{
    // per-call data
    CString* pData;
    CCriticalSection m_critSect;
    CMap < HCONN, HCONN&, CString*, CString* > m_map;

    // allocate per-call data
    DWORD HttpExtensionProc(EXTENSION_CONTROL_BLOCK* pECB);
};

// in your .CPP file, override HttpExtensionProc,
// to set per-call data for this connection
DWORD CISAPIWizExtension::HttpExtensionProc(EXTENSION_CONTROL_BLOCK* pECB)
{
    DWORD dwResult;
    // allocate per-call data
    // using the data type of your choice
    pData = new CString("whatever data you want");
    m_critSect.Lock();
    m_map.SetAt(pECB->ConnID, pData);
    m_critSect.Unlock();


    // call base class to do the work
    // remember, any member functions
    // that use the per-call data
    // must also access it within critical sections
    dwResult = CHttpServer::HttpExtensionProc(pECB);

    // delete per-call data
    m_critSect.Lock();
    m_map.Lookup(pECB->ConnID, pData);
    m_map.RemoveKey(pECB->ConnID);
    delete pData; 
    m_critSect.Unlock();
    return dwResult;
}

Filter Memory Management

Most filters will register for the end of net session event. You can use this event to recycle any buffers used by that client request. For performance reasons, most filters will probably keep a pool of filter buffers and only allocate or free memory when the pool becomes empty or so large it no longer saves on the overhead of memory management. To allocate memory that is automatically freed when the communication with the client is terminated, use CHttpFilterContext::AllocMem. Using AllocMem presents a tradeoff: It is a valuable memory management tool, but it can affect performance, as noted earlier.

See Also   Internet First Steps: Application Design Choices, ISAPI: Debugging, Internet: Where Is..., ISAPI: Debugging