In the last blog entry I went over how we start the runtime.  Once it was loaded we were running managed code, but I glossed over the managers that were present and participating in running the system.  Today we start off with CHostControl::GetHostManager.  CHostControl is CoopFiber’s implementation of IHostControl, and GetHostManager is the only API we implement.

 

HRESULT __stdcall CHostControl::GetHostManager(

   /* [in] */ REFIID riid,

   /* [out] */ void **ppObject)

{

 

      if(riid == IID_IHostTaskManager)

      {

            if(m_pTaskMan == NULL)

            {

                  m_pTaskMan = new CHostTaskManager();

            }

            *ppObject = static_cast<IHostTaskManager*>(m_pTaskMan);

            m_pTaskMan->AddRef();

            return(S_OK);

      }

      else if(riid == IID_IHostSyncManager)

      {

            if(m_pTaskMan == NULL)

            {

                  m_pTaskMan = new CHostTaskManager();

            }

            *ppObject = static_cast<IHostSyncManager*>(m_pTaskMan);

            m_pTaskMan->AddRef();

            return(S_OK);

      }

      return(E_NOINTERFACE);

}

 

What are we doing here?  CHostControl has one task manager.  That task manager actually implements both IHostTaskManager and IHostSyncManager.  These are the minimal APIs you need to implement fiber mode of any sort.  IHostTaskManager provides the mechanisms for creating tasks.  IHostSyncManager provides the mechanisms for providing synchronization between those tasks.

 

At load time, the CLR calls the host-implemented IHostControl interface and asks for the managers that the CLR knows about.  The host can respond by handing back an interface pointer or it can respond by returning E_NOINTERFACE.  Virtually any combination of managers is supported.  The one gotcha is your thread and synchronization must be compatible.  The default synchronization implementation in the CLR is not fiber aware.  That’s the reason that we implement both a task and synchronization manager for this fiber mode sample.

 

Here our GetHostManager implementation simply lazily creates the task manager for the first caller and hands it off to the runtime.  If it’s a manager the host doesn’t know about we return E_NOINTERFACE.

 

The host control also provides a couple of other APIs that we’re not using here.  The first is SetAppDomainManager.  This is where the host is notified of the creation of an app domain.  The host is passed both the ID of the newly created app domain and an IUnknown pointer for the app domain manager.  Because CoopFiber doesn’t use an app domain manager we’ll never get any calls here.  We simply return E_NOTIMPL.

 

The other API is GetDomainNeutralAssemblies.  This is another API that CoopFiber doesn’t use because it doesn’t care whether assemblies are loaded domain neutral or not.  Again, it simply returns E_NOTIMPL.

 

So that’s it for the host control.  Stay tuned for the next entry when I’ll dig into our task manager.  Things will start to get really interesting then!