//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }