Esempio n. 1
0
//---------------------------------------------------------------------------
//	@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;
}
Esempio n. 2
0
//---------------------------------------------------------------------------
//	@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;
}