diff --git a/BeefySysLib/util/ThreadPool.cpp b/BeefySysLib/util/ThreadPool.cpp index 6c0c1cc1..8867373b 100644 --- a/BeefySysLib/util/ThreadPool.cpp +++ b/BeefySysLib/util/ThreadPool.cpp @@ -8,6 +8,7 @@ static BF_TLS_DECLSPEC ThreadPool* gPoolParent; ThreadPool::Thread::Thread() { mCurJobThreadId = -1; + mActiveJob = NULL; } ThreadPool::Thread::~Thread() @@ -34,9 +35,10 @@ void ThreadPool::Thread::Proc() { job = mThreadPool->mJobs[0]; job->mProcessing = true; - mThreadPool->mJobs.RemoveAt(0); + mThreadPool->mJobs.RemoveAt(0); } + mActiveJob = job; if (job == NULL) mCurJobThreadId = -1; else @@ -76,6 +78,7 @@ void ThreadPool::Thread::Proc() // Run dtor synchronized AutoCrit autoCrit(mThreadPool->mCritSect); + mActiveJob = NULL; delete job; } } @@ -176,4 +179,14 @@ void ThreadPool::AddJob(BfpThreadStartProc proc, void* param, int maxWorkersPerP bool ThreadPool::IsInJob() { return gPoolParent == this; +} + +void ThreadPool::CancelAll() +{ + AutoCrit autoCrit(mCritSect); + for (auto job : mJobs) + job->Cancel(); + for (auto thread : mThreads) + if (thread->mActiveJob != NULL) + thread->mActiveJob->Cancel(); } \ No newline at end of file diff --git a/BeefySysLib/util/ThreadPool.h b/BeefySysLib/util/ThreadPool.h index 3f53e432..6c127ecf 100644 --- a/BeefySysLib/util/ThreadPool.h +++ b/BeefySysLib/util/ThreadPool.h @@ -9,12 +9,15 @@ NS_BF_BEGIN class ThreadPool { public: + class Job; + class Thread { public: ThreadPool* mThreadPool; BfpThread* mBfpThread; BfpThreadId mCurJobThreadId; + Job* mActiveJob; public: Thread(); @@ -85,6 +88,7 @@ public: void AddJob(Job* job, int maxWorkersPerProviderThread = 0x7FFFFFFF); void AddJob(BfpThreadStartProc proc, void* param, int maxWorkersPerProviderThread = 0x7FFFFFFF); bool IsInJob(); + void CancelAll(); }; NS_BF_END \ No newline at end of file diff --git a/IDE/BeefProj.toml b/IDE/BeefProj.toml index b6386672..23259bad 100644 --- a/IDE/BeefProj.toml +++ b/IDE/BeefProj.toml @@ -27,7 +27,7 @@ TargetDirectory = "$(WorkspaceDir)/dist" TargetName = "BeefIDE_d" OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib" CLibType = "Dynamic" -DebugCommandArguments = "-test=scripts\\Minidump.txt -testNoExit -verbosity=Diagnostic" +DebugCommandArguments = "-test=scripts\\Minidump.txt -testNoExit -verbosity=diagnostic" DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest" EnvironmentVars = ["_NO_DEBUG_HEAP=1"] diff --git a/IDE/Tests/EmptyTest/scripts/Minidump.txt b/IDE/Tests/EmptyTest/scripts/Minidump.txt index 43a83879..a4e80359 100644 --- a/IDE/Tests/EmptyTest/scripts/Minidump.txt +++ b/IDE/Tests/EmptyTest/scripts/Minidump.txt @@ -1,6 +1,5 @@ SetSymSrvOptions("C:/SymCache", "http://symbols.beeflang.org/\nhttps://msdl.microsoft.com/download/symbols", "TempCache") -#SetSymSrvOptions("C:/SymCache", "https://msdl.microsoft.com/download/symbols\nhttps://chromium-browser-symsrv.commondatastorage.googleapis.com", "TempCache") -#SetSymSrvOptions("C:/SymCache", "https://msdl.microsoft.com/download/symbols\nhttps://chromium-browser-symsrv.commondatastorage.googleapis.com", "None") +#SetSymSrvOptions("C:/SymCache", "http://127.0.0.1:8042", "TempCache") OpenCrashDump("dumps/Chrome1.dmp") WaitForPaused() diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 445cb681..45e34fed 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -6292,6 +6292,8 @@ namespace IDE mVerbosity = .Detailed; else if (value == "diagnostic") mVerbosity = .Diagnostic; + else + Fail(scope String()..AppendF("Invalid verbosity option: {}", value)); case "-workspace","-proddir": var relDir = scope String(value); if ((relDir.EndsWith("\\")) || relDir.EndsWith("\"")) @@ -10465,7 +10467,7 @@ namespace IDE bool isOutput = (cmd == "msg") || (cmd == "dbgEvalMsg") || (cmd == "log"); if (cmd == "msgLo") { - if (mVerbosity <= .Diagnostic) + if (mVerbosity < .Diagnostic) continue; isOutput = true; } diff --git a/IDEHelper/NetManager.cpp b/IDEHelper/NetManager.cpp index 7edbb6f6..2d8c35b6 100644 --- a/IDEHelper/NetManager.cpp +++ b/IDEHelper/NetManager.cpp @@ -9,6 +9,7 @@ USING_NS_BF; #ifdef BF_CURL #define CURL_STATICLIB #include "curl/curl.h" +#include "curl/multi.h" static int TransferInfoCallback(void* userp, curl_off_t dltotal, curl_off_t dlnow, @@ -80,8 +81,18 @@ static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, voi void NetRequest::Cleanup() { + if (mCURLMulti != NULL) + { + curl_multi_remove_handle(mCURLMulti, mCURL); + } + if (mCURL != NULL) curl_easy_cleanup(mCURL); + + if (mCURLMulti != NULL) + { + curl_multi_cleanup(mCURLMulti); + } } void NetRequest::Perform() @@ -98,7 +109,9 @@ void NetRequest::Perform() mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str())); mOutTempPath = mOutPath + "__partial"; - + + mCURLMulti = curl_multi_init(); + mCURL = curl_easy_init(); if (mShowTracking) @@ -115,13 +128,37 @@ void NetRequest::Perform() curl_easy_setopt(mCURL, CURLOPT_XFERINFOFUNCTION, TransferInfoCallback); curl_easy_setopt(mCURL, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(mCURL, CURLOPT_NOPROGRESS, 0L); - auto result = curl_easy_perform(mCURL); + //auto result = curl_easy_perform(mCURL); - if (result != CURLE_OK) + CURLMcode mcode = curl_multi_add_handle(mCURLMulti, mCURL); + if (mcode != CURLM_OK) { mFailed = true; return; } + + while (true) + { + int activeCount = 0; + curl_multi_perform(mCURLMulti, &activeCount); + if (activeCount == 0) + break; + + int waitRet = 0; + curl_multi_wait(mCURLMulti, NULL, 0, 20, &waitRet); + + if (mCancelling) + { + mFailed = true; + return; + } + } + +// if (result != CURLE_OK) +// { +// mFailed = true; +// return; +// } long response_code = 0; curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code); @@ -375,6 +412,7 @@ void NetManagerThread() NetManager::NetManager() : mThreadPool(8, 1*1024*1024) { mWaitingResult = NULL; + mWaitingRequest = NULL; } NetManager::~NetManager() @@ -458,7 +496,7 @@ bool NetManager::Get(const StringImpl& url, const StringImpl& destPath) break; } - mWaitingResult = netResult; + mWaitingResult = netResult; netResult->mCurRequest->ShowTracking(); } } @@ -474,10 +512,16 @@ bool NetManager::Get(const StringImpl& url, const StringImpl& destPath) } // Perform this in the requesting thread + { + AutoCrit autoCrit(mThreadPool.mCritSect); + mWaitingRequest = netRequest; + } + netRequest->mShowTracking = true; netRequest->Perform(); AutoCrit autoCrit(mThreadPool.mCritSect); + mWaitingRequest = NULL; auto netResult = netRequest->mResult; delete netRequest; @@ -490,11 +534,9 @@ bool NetManager::Get(const StringImpl& url, const StringImpl& destPath) void NetManager::CancelAll() { AutoCrit autoCrit(mThreadPool.mCritSect); - for (auto job : mThreadPool.mJobs) - { - auto netRequest = (NetRequest*)job; - netRequest->Cancel(); - } + if (mWaitingRequest != NULL) + mWaitingRequest->Cancel(); + mThreadPool.CancelAll(); } void NetManager::Clear() @@ -528,8 +570,9 @@ void NetManager::Clear() void NetManager::CancelCurrent() { AutoCrit autoCrit(mThreadPool.mCritSect); - - if ((mWaitingResult != NULL) && (mWaitingResult->mCurRequest != NULL)) + if (mWaitingRequest != NULL) + mWaitingRequest->Cancel(); + else if ((mWaitingResult != NULL) && (mWaitingResult->mCurRequest != NULL)) mWaitingResult->mCurRequest->Cancel(); } diff --git a/IDEHelper/NetManager.h b/IDEHelper/NetManager.h index e923b992..d3f62a8e 100644 --- a/IDEHelper/NetManager.h +++ b/IDEHelper/NetManager.h @@ -17,6 +17,7 @@ class NetResult; #ifdef BF_CURL typedef void CURL; +typedef void CURLM; #endif class NetRequest : public ThreadPool::Job @@ -30,9 +31,10 @@ public: FileStream mOutFile; #ifdef BF_CURL CURL* mCURL; + CURLM* mCURLMulti; #else #endif - bool mCancelling; + volatile bool mCancelling; bool mFailed; String mError; uint32 mLastUpdateTick; @@ -45,6 +47,7 @@ public: mLastUpdateTick = 0; #ifdef BF_CURL mCURL = NULL; + mCURLMulti = NULL; #else #endif mCancelling = false; @@ -90,6 +93,7 @@ public: Array mOldResults; SyncEvent mRequestDoneEvent; NetResult* mWaitingResult; + NetRequest* mWaitingRequest; public: NetManager();