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
00076 }
00077
00088 bool
00089 CCoContext::Go() {
00090
00091
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
00097 if (!m_pFiber) {
00098 m_dwThreadId = GetCurrentThreadId();
00099
00100 if (!m_pfStart) {
00101
00102
00103 if (TlsGetValue(dwTlsIndex) == NULL) {
00104
00105 m_pFiber = ConvertThreadToFiber(0);
00106
00107
00108 TlsSetValue(dwTlsIndex, (LPVOID)true);
00109 } else {
00110
00111 m_pFiber = GetCurrentFiber();
00112 }
00113
00114
00115
00116
00117
00118 return true;
00119 }
00120
00121
00122
00123 m_pFiber = CreateFiber(0, Start, this);
00124
00125 }
00126
00127 ASSCHK(TlsGetValue(dwTlsIndex) != NULL, _T("CoContext::Go() [Attempt to switch to fiber from non-fiber]"));
00128
00129
00130 SwitchToFiber(m_pFiber);
00131
00132 return true;
00133 }
00134
00143 void
00144 CCoContext::Stop() {
00145
00146 if (m_pFiber && m_pfStart) {
00147
00148 if (m_pFiber != GetCurrentFiber()) {
00149
00150 DeleteFiber(m_pFiber);
00151 m_pFiber = NULL;
00152 } else {
00153
00154 ASSCHK(false, _T("Attempting to stop self"));
00155 }
00156 }
00157 }
00158 };