//--------------------------------------------------------------------------- // @function: // CAutoTaskProxy::Create // // @doc: // Create new task; // Bind task to function and argument and associate with task and error context; // If caller is a task, its task context is cloned and used by the new task; // //--------------------------------------------------------------------------- CTask * CAutoTaskProxy::Create ( void *(*pfunc)(void*), void *arg, volatile BOOL *cancel ) { // create memory pool for task CAutoMemoryPool amp(CAutoMemoryPool::ElcStrict); IMemoryPool *mp = amp.Pmp(); // auto pointer to hold new task context CAutoP<CTaskContext> task_ctxt; // check if caller is a task ITask *task_parent = CWorker::Self()->GetTask(); if (NULL == task_parent) { // create new task context task_ctxt = GPOS_NEW(mp) CTaskContext(mp); } else { // clone parent task's context task_ctxt = GPOS_NEW(mp) CTaskContext(mp, *task_parent->GetTaskCtxt()); } // auto pointer to hold error context CAutoP<CErrorContext> err_ctxt; err_ctxt = GPOS_NEW(mp) CErrorContext(); CTask *task = CTask::Self(); if (NULL != task) { err_ctxt.Value()->Register(task->ConvertErrCtxt()->GetMiniDumper()); } // auto pointer to hold new task // task is created inside ATP's memory pool CAutoP<CTask> new_task; new_task = GPOS_NEW(m_mp) CTask(mp, task_ctxt.Value(), err_ctxt.Value(), &m_event, cancel); // reset auto pointers - task now handles task and error context (void) task_ctxt.Reset(); (void) err_ctxt.Reset(); // detach task's memory pool from auto memory pool amp.Detach(); // bind function and argument task = new_task.Value(); task->Bind(pfunc, arg); // add to task list m_list.Append(task); // reset auto pointer - ATP now handles task new_task.Reset(); // register task to worker pool m_pwpm->RegisterTask(task); return task; }
//--------------------------------------------------------------------------- // @function: // CAutoTaskProxy::PtskCreate // // @doc: // Create new task; // Bind task to function and argument and associate with task and error context; // If caller is a task, its task context is cloned and used by the new task; // //--------------------------------------------------------------------------- CTask * CAutoTaskProxy::PtskCreate ( void *(*pfunc)(void*), void *pvArg, volatile BOOL *pfCancel ) { // create memory pool for task CAutoMemoryPool amp(CAutoMemoryPool::ElcStrict); IMemoryPool *pmp = amp.Pmp(); // auto pointer to hold new task context CAutoP<CTaskContext> aptc; // check if caller is a task ITask *ptskParent = CWorker::PwrkrSelf()->Ptsk(); if (NULL == ptskParent) { // create new task context aptc = GPOS_NEW(pmp) CTaskContext(pmp); } else { // clone parent task's context aptc = GPOS_NEW(pmp) CTaskContext(pmp, *ptskParent->Ptskctxt()); } // auto pointer to hold error context CAutoP<CErrorContext> apec; apec = GPOS_NEW(pmp) CErrorContext(); CTask *ptsk = CTask::PtskSelf(); if (NULL != ptsk) { apec.Pt()->Register(ptsk->PerrctxtConvert()->Pmdr()); } // auto pointer to hold new task // task is created inside ATP's memory pool CAutoP<CTask> apt; apt = GPOS_NEW(m_pmp) CTask(pmp, aptc.Pt(), apec.Pt(), &m_event, pfCancel); // reset auto pointers - task now handles task and error context (void) aptc.PtReset(); (void) apec.PtReset(); // detach task's memory pool from auto memory pool amp.PmpDetach(); // bind function and argument ptsk = apt.Pt(); ptsk->Bind(pfunc, pvArg); // add to task list m_list.Append(ptsk); // reset auto pointer - ATP now handles task apt.PtReset(); // register task to worker pool m_pwpm->RegisterTask(ptsk); return ptsk; }