//--------------------------------------------------------------------------- // @function: // CAutoTaskProxyTest::EresUnittest_Cancel // // @doc: // Cancel and destroy tasks while queued/executing // //--------------------------------------------------------------------------- GPOS_RESULT CAutoTaskProxyTest::EresUnittest_Destroy() { const ULONG culTskCnt = 90; CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); CWorkerPoolManager *pwpm = CWorkerPoolManager::Pwpm(); // scope for ATP { CAutoTaskProxy atp(pmp, pwpm); CTask *rgPtsk[culTskCnt]; ULLONG rgRes[culTskCnt]; CTask *ptsk = NULL; atp.SetPropagateError(false /* fPropagateError */); for (ULONG i = 0; i < culTskCnt / 3; i++) { GPOS_CHECK_ABORT; // create 3 tasks rgPtsk[3*i] = atp.PtskCreate(CAutoTaskProxyTest::PvUnittest_Short, &rgRes[3*i]); rgPtsk[3*i + 1] = atp.PtskCreate(CAutoTaskProxyTest::PvUnittest_Long, &rgRes[3*i + 1]); rgPtsk[3*i + 2] = atp.PtskCreate(CAutoTaskProxyTest::PvUnittest_Infinite, &rgRes[3*i + 2]); atp.Schedule(rgPtsk[3*i]); atp.Schedule(rgPtsk[3*i + 1]); atp.Schedule(rgPtsk[3*i + 2]); // cancel one task atp.Cancel(rgPtsk[3*i + 2]); // destroy completed tasks while (0 < atp.UlTasks() && GPOS_OK == atp.EresTimedWaitAny(&ptsk, 0)) { GPOS_ASSERT(CTask::EtsCompleted == ptsk->Ets() || ptsk->FCanceled()); atp.Destroy(ptsk); } } // ATP cancels running task } return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // gpos_exec // // @doc: // Execute function as a GPOS task using current thread; // return 0 for successful completion, 1 for error; // //--------------------------------------------------------------------------- int gpos_exec ( gpos_exec_params *params ) { // check if passed parameters are valid if (NULL == params || NULL == params->func) { return 1; } try { CWorkerPoolManager *pwpm = CWorkerPoolManager::Pwpm(); // check if worker pool is initialized if (NULL == pwpm) { return 1; } // if no stack start address is passed, use address in current stack frame void *pvStackStart = params->stack_start; if (NULL == pvStackStart) { pvStackStart = &pwpm; } // put worker to stack - main thread has id '0' CWorker wrkr(0, GPOS_WORKER_STACK_SIZE, (ULONG_PTR) pvStackStart); // scope for memory pool { // setup task memory CAutoMemoryPool amp(CAutoMemoryPool::ElcStrict); IMemoryPool *pmp = amp.Pmp(); // scope for ATP { // task handler for this process CAutoTaskProxy atp(pmp, pwpm, false/*fPropagateError*/); CTask *ptsk = atp.PtskCreate(params->func, params->arg, params->abort_requested); // init TLS ptsk->Tls().Reset(pmp); CAutoP<CWStringStatic> apwstr; CAutoP<COstreamString> aposs; CAutoP<CLoggerStream> aplogger; // use passed buffer for logging if (NULL != params->error_buffer) { GPOS_ASSERT(0 < params->error_buffer_size); apwstr = GPOS_NEW(pmp) CWStringStatic ( (WCHAR *) params->error_buffer, params->error_buffer_size / GPOS_SIZEOF(WCHAR) ); aposs = GPOS_NEW(pmp) COstreamString(apwstr.Pt()); aplogger = GPOS_NEW(pmp) CLoggerStream(*aposs.Pt()); CTaskContext *ptskctxt = ptsk->Ptskctxt(); ptskctxt->SetLogOut(aplogger.Pt()); ptskctxt->SetLogErr(aplogger.Pt()); } // execute function atp.Execute(ptsk); // export task result params->result = ptsk->PvRes(); // check for errors during execution if (CTask::EtsError == ptsk->Ets()) { return 1; } } } } catch(CException ex) { std::cerr << "Unexpected exception reached top of execution stack:" << " major=" << ex.UlMajor() << " minor=" << ex.UlMinor() << " file=" << ex.SzFilename() << " line=" << ex.UlLine() << std::endl; // unexpected failure return 1; } catch (...) { // unexpected failure return 1; } return 0; }