Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

CCoContext.cpp

Go to the documentation of this file.
00001 
00034 #include "stdafx.h"
00035 
00036 namespace AxPipe {
00046     CCoContext::CCoContext(CError *pErr, void (*pfStart)(void *), void *pvParam) {
00047         m_pFiber = NULL;
00048         Init(pErr, pfStart, pvParam);
00049     }
00050 
00055     void
00056     CCoContext::Init(CError *pErr, void (*pfStart)(void *), void *pvParam) {
00057         m_pErr = pErr;
00058         m_pfStart = pfStart;
00059         m_pvParam = pvParam;
00060     }
00061     
00067     CCoContext::~CCoContext() {
00068         Stop();
00069     }
00070 
00072     VOID CALLBACK
00073     CCoContext::Start(PVOID lpParam) {
00074         ((CCoContext *)lpParam)->m_pfStart(((CCoContext *)lpParam)->m_pvParam);
00075         // Should never get here.
00076     }
00077     
00088     bool
00089     CCoContext::Go() {
00090         // First assure we really do have a TLS index. If we don't - this is
00091         // an error condition.
00092         if (dwTlsIndex == TLS_OUT_OF_INDEXES) {
00093             m_pErr->SetError(ERROR_CODE_INTERNAL, ERROR_MSG_INTERNAL, _T("CoContext::Go() [No TLS available]"));
00094             return false;
00095         }
00096         // If this is the first call to Go() - i.e. initialize
00097         if (!m_pFiber) {
00098             m_dwThreadId = GetCurrentThreadId();
00099             // If we're to initialize in the current context
00100             if (!m_pfStart) {
00101                 //OutputDebugString(_T("CCoContext::Go() !m_pfStart Init in current context\n"));
00102                 // If we're not a fiber, we need to convert to one.
00103                 if (TlsGetValue(dwTlsIndex) == NULL) {
00104                     //OutputDebugString(_T("CCoContext::Go() ConvertThreadToFiber(0)\n"));
00105                     m_pFiber = ConvertThreadToFiber(0);
00106                     // And now we've converted to one, we need to remember that this thread
00107                     // is now a fiber. If we have TLS, we set the value to true to inidcate this.
00108                     TlsSetValue(dwTlsIndex, (LPVOID)true);
00109                 } else {
00110                     //OutputDebugString(_T("CCoContext::Go() GetCurrentFiber()\n"));
00111                     m_pFiber = GetCurrentFiber();
00112                 }
00113                 // Now m_pFiber is the current fiber.
00114 
00115                 // We must guard against effectively doing SwitchToFiber(GetCurrentFiber())
00116                 // Since we're just initializing this context, and want to remain here,
00117                 // we just do a return.
00118                 return true;
00119             }
00120             // We're to create a new fiber with a specific starting point, so
00121             // let's do that.
00122             //OutputDebugString(_T("CCoContext::Go() CreateFiber(0, Start, this)\n"));
00123             m_pFiber = CreateFiber(0, Start, this);
00124             // ...we fall through below to actually start the fiber too.
00125         }
00126         // Here the thread must have been converted to a fiber, to allow the switch.
00127         ASSCHK(TlsGetValue(dwTlsIndex) != NULL, _T("CoContext::Go() [Attempt to switch to fiber from non-fiber]"));
00128 //        ASSCHK(m_dwThreadId == GetCurrentThreadId(), _T("CoContext::Go() [Attempt to schedule fiber in different thread]"));
00129         //OutputDebugString(_T("CCoContext::Go() SwitchToFiber()\n"));
00130         SwitchToFiber(m_pFiber);
00131         // Now we're back, because someone switched to us
00132         return true;
00133     }
00134 
00143     void
00144     CCoContext::Stop() {
00145         // If we have a StartProc and we have a fiber...
00146         if (m_pFiber && m_pfStart) {
00147             // ...and this fiber is not the current fiber...
00148             if (m_pFiber != GetCurrentFiber()) {
00149                 // ... then we delete it, and forget it.
00150                 DeleteFiber(m_pFiber);
00151                 m_pFiber = NULL;
00152             } else {
00153                 // ... otherwise we're trying to stop ourselves, which we can't do.
00154                 ASSCHK(false, _T("Attempting to stop self"));
00155             }
00156         }
00157     }
00158 };

Generated on Mon Feb 2 13:19:18 2004 for AxPipe by doxygen 1.3.5