Skip to content

Commit

Permalink
Fixes badly closed curl thread when cancelled
Browse files Browse the repository at this point in the history
  • Loading branch information
AurL committed Mar 9, 2016
1 parent 1f085f9 commit 7ed25e7
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
14 changes: 6 additions & 8 deletions Win/PublishSkfb.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ int doPublishSkfb(HINSTANCE hInst,HWND hWnd);
INT_PTR CALLBACK managePublishWindow(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
INT_PTR CALLBACK manageUploadWindow(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);
HANDLE uploadThreadHandle = NULL;
SketchfabV2Uploader* uploader;

LPCWSTR stringToLpwstr(std::string input)
{
Expand Down Expand Up @@ -96,8 +97,8 @@ int doPublishSkfb(HINSTANCE hInst,HWND hWnd)
DWORD WINAPI thread_func(LPVOID lpParameter)
{
UNREFERENCED_PARAMETER(lpParameter);
SketchfabV2Uploader uploader;
lastResponse = uploader.upload(uploadWindow, skfbPbdata.skfbApiToken, skfbPbdata.skfbFilePath, skfbPbdata.skfbName, skfbPbdata.skfbDescription, skfbPbdata.skfbTags, skfbPbdata.skfbDraft, skfbPbdata.skfbPrivate, skfbPbdata.skfbPassword);
uploader = new SketchfabV2Uploader();
lastResponse = uploader->upload(uploadWindow, skfbPbdata.skfbApiToken, skfbPbdata.skfbFilePath, skfbPbdata.skfbName, skfbPbdata.skfbDescription, skfbPbdata.skfbTags, skfbPbdata.skfbDraft, skfbPbdata.skfbPrivate, skfbPbdata.skfbPassword);
SendMessage(uploadWindow, SIGNAL_UPLOAD_FINISHED, 100, 0);
return 0;
}
Expand Down Expand Up @@ -138,6 +139,7 @@ INT_PTR CALLBACK manageUploadWindow(HWND hDlg,UINT message,WPARAM wParam,LPARAM
errorMessageStr.c_str(),
L"Upload failed",
MB_OKCANCEL | MB_ICONERROR);
delete uploader;
}

EndDialog(hDlg, (INT_PTR)TRUE);
Expand All @@ -148,12 +150,8 @@ INT_PTR CALLBACK manageUploadWindow(HWND hDlg,UINT message,WPARAM wParam,LPARAM
switch (LOWORD(wParam))
{
case IDC_SKFB_UPLOAD_CANCEL:
// Terminate thread
TerminateThread(uploadThreadHandle, 1);
EndDialog(hDlg, (INT_PTR)FALSE);
MessageBox(NULL,
_T("Upload cancelled by the user"), _T("Upload interrupted"), MB_OK | MB_ICONERROR);
return (INT_PTR)FALSE;
// Ask curl to stop upload
uploader->abort();
}
break;
}
Expand Down
23 changes: 18 additions & 5 deletions Win/SketchfabUploader.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ typedef std::map<std::string, std::string> attributes;
struct ProgressbarUpdater {
CURL *curl;
HWND progressBar;
bool cancel;
};

// Taken from https://curl.haxx.se/libcurl/c/progressfunc.html
Expand All @@ -22,11 +23,12 @@ int progress_callback(void *clientp,

UNREFERENCED_PARAMETER(dltotal);
UNREFERENCED_PARAMETER(dlnow);
// Hack to smooth the progress bar

struct ProgressbarUpdater *myp = (struct ProgressbarUpdater *)clientp;
double curtime = 0;

if(myp->cancel)
return 1;

double curtime = 0;
curl_easy_getinfo(myp->curl, CURLINFO_TOTAL_TIME, &curtime);

curl_off_t total_percen = 0;
Expand All @@ -45,7 +47,13 @@ static size_t WriteMemoryCallback(char *contents, size_t size, size_t nmemb, voi
}

class SketchfabV2Uploader {
private:
struct ProgressbarUpdater prog;
public:
void abort()
{
prog.cancel=true;
}
std::pair<bool, std::string> upload(HWND progressBar,
const std::string& token,
const std::string& filepath,
Expand Down Expand Up @@ -90,7 +98,6 @@ class SketchfabV2Uploader {
HWND progressBar=NULL)
{
CURL *curl;
struct ProgressbarUpdater prog;
CURLcode res;
long http_code;
std::string response;
Expand Down Expand Up @@ -132,6 +139,7 @@ class SketchfabV2Uploader {
if (curl) {
prog.curl = curl;
prog.progressBar = progressBar;
prog.cancel = false;

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
Expand All @@ -142,9 +150,14 @@ class SketchfabV2Uploader {
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 900L);
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);

res = curl_easy_perform(curl);
if (res != CURLE_OK) {
return std::pair<int, std::string>(1, "{\"detail\":\"curl_easy_perform() failed: " + std::string(curl_easy_strerror(res)) + "\" } ");
// Upload has been cancelled
if(prog.cancel)
return std::pair<int, std::string>(1, "{\"detail\":\" Canceled by the user\" } ");
else
return std::pair<int, std::string>(1, "{\"detail\":\"curl_easy_perform() failed: " + std::string(curl_easy_strerror(res)) + "\" } ");
}
else {
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
Expand Down

0 comments on commit 7ed25e7

Please sign in to comment.