예제 #1
0
//---------------------------------------------------------------------------
//	@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;
}
예제 #2
0
파일: _api.cpp 프로젝트: RalphSu/gpos
//---------------------------------------------------------------------------
//	@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;
}