예제 #1
0
//---------------------------------------------------------------------------
//	@function:
//		CMDProviderTest::EresUnittest_Negative
//
//	@doc:
//		Test fetching non-exiting metadata objects from a file-based provider
//
//---------------------------------------------------------------------------
GPOS_RESULT
CMDProviderTest::EresUnittest_Negative()
{
	CAutoMemoryPool amp(CAutoMemoryPool::ElcNone);
	IMemoryPool *pmp = amp.Pmp();
	
	CMDProviderMemory *pmdpFile = GPOS_NEW(pmp) CMDProviderMemory(pmp, szFileName);
	pmdpFile->AddRef();
	
	// we need to use an auto pointer for the cache here to ensure
	// deleting memory of cached objects when we throw
	CAutoP<CMDAccessor::MDCache> apcache;
	apcache = CCacheFactory::PCacheCreate<gpopt::IMDCacheObject*, gpopt::CMDKey*>
				(
				true, // fUnique
				0 /* unlimited cache quota */,
				CMDKey::UlHashMDKey,
				CMDKey::FEqualMDKey
				);

	CMDAccessor::MDCache *pcache = apcache.Pt();

	{
		CAutoMDAccessor amda(pmp, pmdpFile, CTestUtils::m_sysidDefault, pcache);

		// lookup a non-existing objects
		CMDIdGPDB *pmdid = GPOS_NEW(pmp) CMDIdGPDB(GPOPT_MDCACHE_TEST_OID, 15 /* major version */, 1 /* minor version */);

		// call should result in an exception
		(void) pmdpFile->PstrObject(pmp, amda.Pmda(), pmdid);
	}
	
	return GPOS_FAILED;
}
예제 #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;
}
예제 #3
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;
}