diff --git a/src/engine/client/fetcher.cpp b/src/engine/client/fetcher.cpp index 4357db71d..70b2857cb 100644 --- a/src/engine/client/fetcher.cpp +++ b/src/engine/client/fetcher.cpp @@ -15,7 +15,6 @@ class CFetchTask : public IFetchTask friend class CFetcher; class CFetcher *m_pFetcher; - CJob m_Job; CURL *m_pHandle; void *m_pUser; @@ -35,6 +34,7 @@ class CFetchTask : public IFetchTask bool m_Abort; bool m_Destroy; + bool m_PastCB; public: virtual double Current() { return m_Current; } @@ -49,7 +49,7 @@ public: void CFetchTask::Destroy() { - if(m_Job.Status() == CJob::STATE_DONE) + if(m_PastCB) { delete this; } @@ -76,6 +76,18 @@ void CFetcher::Escape(char *pBuf, size_t size, const char *pStr) curl_free(pEsc); } +void CFetcher::DestroyCallback(CJob *pJob, void *pUser) +{ + CFetchTask *pTask = (CFetchTask *)pUser; + + delete pJob; + + if(pTask->m_Destroy) + delete pTask; + + pTask->m_PastCB = true; +} + IFetchTask *CFetcher::FetchFile(const char *pUrl, const char *pDest, int StorageType, bool UseDDNetCA, bool CanTimeout, void *pUser, COMPFUNC pfnCompCb, PROGFUNC pfnProgCb) { CFetchTask *pTask = new CFetchTask; @@ -92,10 +104,13 @@ IFetchTask *CFetcher::FetchFile(const char *pUrl, const char *pDest, int Storage pTask->m_Abort = false; pTask->m_Destroy = false; + pTask->m_PastCB = false; pTask->m_Size = pTask->m_Progress = 0; pTask->m_State = IFetchTask::STATE_QUEUED; - m_pEngine->AddJob(&pTask->m_Job, FetcherThread, pTask); + + CJob *pJob = new CJob; + m_pEngine->AddJob(pJob, FetcherThread, pTask, DestroyCallback); return pTask; } @@ -180,9 +195,6 @@ int CFetcher::FetcherThread(void *pUser) if(pTask->m_pfnCompCallback) pTask->m_pfnCompCallback(pTask, pTask->m_pUser); - if(pTask->m_Destroy) - delete pTask; - return(ret != CURLE_OK) ? 1 : 0; } diff --git a/src/engine/client/fetcher.h b/src/engine/client/fetcher.h index 59303f213..77319f187 100644 --- a/src/engine/client/fetcher.h +++ b/src/engine/client/fetcher.h @@ -15,6 +15,7 @@ public: virtual IFetchTask *FetchFile(const char *pUrl, const char *pDest, int StorageType = -2, bool UseDDNetCA = false, bool CanTimeout = true, void *pUser = 0, COMPFUNC pfnCompCb = 0, PROGFUNC pfnProgCb = 0); virtual void Escape(char *pBud, size_t size, const char *pStr); + static void DestroyCallback(CJob *pJob, void *pUser); static int FetcherThread(void *pUser); static size_t WriteToFile(char *pData, size_t size, size_t nmemb, void *pFile); static int ProgressCallback(void *pUser, double DlTotal, double DlCurr, double UlTotal, double UlCurr); diff --git a/src/engine/engine.h b/src/engine/engine.h index d0d53dc3a..6273b1b0a 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -26,7 +26,7 @@ public: virtual void Init() = 0; virtual void InitLogfile() = 0; virtual void HostLookup(CHostLookup *pLookup, const char *pHostname, int Nettype) = 0; - virtual void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData) = 0; + virtual void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCB = 0) = 0; }; extern IEngine *CreateEngine(const char *pAppname, bool Silent); diff --git a/src/engine/shared/engine.cpp b/src/engine/shared/engine.cpp index dc401c476..773088bc9 100644 --- a/src/engine/shared/engine.cpp +++ b/src/engine/shared/engine.cpp @@ -106,11 +106,11 @@ public: AddJob(&pLookup->m_Job, HostLookupThread, pLookup); } - void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData) + void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCB = 0) { if(g_Config.m_Debug) dbg_msg("engine", "job added"); - m_JobPool.Add(pJob, pfnFunc, pData); + m_JobPool.Add(pJob, pfnFunc, pData, pfnCB); } }; diff --git a/src/engine/shared/jobs.cpp b/src/engine/shared/jobs.cpp index d89e5ada0..8c7e635ee 100644 --- a/src/engine/shared/jobs.cpp +++ b/src/engine/shared/jobs.cpp @@ -53,6 +53,8 @@ void CJobPool::WorkerThread(void *pUser) pJob->m_Status = CJob::STATE_RUNNING; pJob->m_Result = pJob->m_pfnFunc(pJob->m_pFuncData); pJob->m_Status = CJob::STATE_DONE; + if(pJob->m_pfnCallback) + pJob->m_pfnCallback(pJob, pJob->m_pFuncData); } } @@ -67,11 +69,12 @@ int CJobPool::Init(int NumThreads) return 0; } -int CJobPool::Add(CJob *pJob, JOBFUNC pfnFunc, void *pData) +int CJobPool::Add(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCallback) { mem_zero(pJob, sizeof(CJob)); pJob->m_pfnFunc = pfnFunc; pJob->m_pFuncData = pData; + pJob->m_pfnCallback = pfnCallback; lock_wait(m_Lock); diff --git a/src/engine/shared/jobs.h b/src/engine/shared/jobs.h index dfaf5df42..edd3c99a4 100644 --- a/src/engine/shared/jobs.h +++ b/src/engine/shared/jobs.h @@ -2,10 +2,12 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #ifndef ENGINE_SHARED_JOBS_H #define ENGINE_SHARED_JOBS_H -typedef int (*JOBFUNC)(void *pData); - +class CJob; class CJobPool; +typedef int (*JOBFUNC)(void *pData); +typedef void (*CBFUNC)(CJob *pJob, void *pData); + class CJob { friend class CJobPool; @@ -17,6 +19,7 @@ class CJob volatile int m_Result; JOBFUNC m_pfnFunc; + CBFUNC m_pfnCallback; void *m_pFuncData; public: CJob() @@ -58,6 +61,6 @@ public: ~CJobPool(); int Init(int NumThreads); - int Add(CJob *pJob, JOBFUNC pfnFunc, void *pData); + int Add(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCallback = 0); }; #endif