mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
[Network] and [Kernal] add cancel from thread (linux)
This commit is contained in:
@ -56,6 +56,8 @@ namespace NSNetwork
|
||||
virtual void Suspend() = 0;
|
||||
virtual void Resume() = 0;
|
||||
virtual void Stop() = 0;
|
||||
virtual void StopNoJoin() = 0;
|
||||
virtual void Cancel() = 0;
|
||||
virtual int IsRunned() = 0;
|
||||
|
||||
//events
|
||||
@ -92,6 +94,8 @@ namespace NSNetwork
|
||||
virtual void Suspend();
|
||||
virtual void Resume();
|
||||
virtual void Stop();
|
||||
virtual void StopNoJoin();
|
||||
virtual void Cancel();
|
||||
virtual int IsRunned();
|
||||
virtual void SetEvent_OnProgress(std::function<void(int)>);
|
||||
virtual void SetEvent_OnComplete(std::function<void(int)>);
|
||||
@ -122,6 +126,8 @@ namespace NSNetwork
|
||||
virtual void Suspend();
|
||||
virtual void Resume();
|
||||
virtual void Stop();
|
||||
virtual void StopNoJoin();
|
||||
virtual void Cancel();
|
||||
virtual int IsRunned();
|
||||
virtual void SetEvent_OnProgress(std::function<void(int)>);
|
||||
virtual void SetEvent_OnComplete(std::function<void(int)>);
|
||||
|
||||
@ -101,6 +101,8 @@ namespace NSNetwork
|
||||
void CFileDownloader::Suspend() { m_pInternal->Suspend(); }
|
||||
void CFileDownloader::Resume() { m_pInternal->Resume(); }
|
||||
void CFileDownloader::Stop() { m_pInternal->Stop(); }
|
||||
void CFileDownloader::StopNoJoin() { m_pInternal->StopNoJoin(); }
|
||||
void CFileDownloader::Cancel() { m_pInternal->Cancel(); }
|
||||
int CFileDownloader::IsRunned() { return m_pInternal->IsRunned(); }
|
||||
|
||||
void CFileDownloader::SetEvent_OnProgress(std::function<void(int)> func)
|
||||
@ -164,6 +166,8 @@ namespace NSNetwork
|
||||
void CFileUploader::Suspend() { m_pInternal->Suspend(); }
|
||||
void CFileUploader::Resume() { m_pInternal->Resume(); }
|
||||
void CFileUploader::Stop() { m_pInternal->Stop(); }
|
||||
void CFileUploader::StopNoJoin() { m_pInternal->StopNoJoin(); }
|
||||
void CFileUploader::Cancel() { m_pInternal->Cancel(); }
|
||||
int CFileUploader::IsRunned() { return m_pInternal->IsRunned(); }
|
||||
|
||||
void CFileUploader::SetEvent_OnProgress(std::function<void(int)> func)
|
||||
|
||||
@ -241,7 +241,7 @@ namespace NSNetwork
|
||||
if (NSFile::CFileBinary::Exists(m_sDownloadFilePath))
|
||||
NSFile::CFileBinary::Remove(m_sDownloadFilePath);
|
||||
}
|
||||
return download_external(m_sDownloadFileUrl, m_sDownloadFilePath, m_func_onProgress);
|
||||
return download_external(m_sDownloadFileUrl, m_sDownloadFilePath, m_func_onProgress, m_bIsExit);
|
||||
}
|
||||
virtual int UploadData() override
|
||||
{
|
||||
|
||||
@ -61,6 +61,8 @@ namespace NSNetwork
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
|
||||
CFileTransporterBase(const std::wstring &sUploadUrl, const unsigned char* cData, const int nSize)
|
||||
@ -82,6 +84,8 @@ namespace NSNetwork
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
|
||||
CFileTransporterBase(const std::wstring &sUploadUrl, const std::wstring &sUploadFilePath)
|
||||
@ -103,6 +107,8 @@ namespace NSNetwork
|
||||
|
||||
m_func_onComplete = NULL;
|
||||
m_func_onProgress = NULL;
|
||||
|
||||
m_bIsExit = nullptr;
|
||||
}
|
||||
|
||||
virtual ~CFileTransporterBase ()
|
||||
@ -143,6 +149,8 @@ namespace NSNetwork
|
||||
|
||||
std::function<void(int)> m_func_onComplete;
|
||||
std::function<void(int)> m_func_onProgress;
|
||||
|
||||
std::atomic<bool>* m_bIsExit; // Для остановки и выхода потока
|
||||
};
|
||||
|
||||
class CFileTransporter_private : public NSThreads::CBaseThread
|
||||
@ -234,6 +242,7 @@ namespace NSNetwork
|
||||
virtual DWORD ThreadProc ()
|
||||
{
|
||||
m_pInternal->m_bComplete = false;
|
||||
m_pInternal->m_bIsExit = NSThreads::CBaseThread::m_bIsExit;
|
||||
|
||||
int hrResultAll = 0;
|
||||
if(m_pInternal->m_eLoadType == m_pInternal->DOWNLOADFILE)
|
||||
@ -245,6 +254,11 @@ namespace NSNetwork
|
||||
|
||||
if (0 == hrResultAll)
|
||||
m_pInternal->m_bComplete = true;
|
||||
else
|
||||
{
|
||||
if (NSFile::CFileBinary::Exists(m_pInternal->m_sDownloadFilePath))
|
||||
NSFile::CFileBinary::Remove(m_pInternal->m_sDownloadFilePath);
|
||||
}
|
||||
|
||||
if (m_pInternal->m_func_onComplete)
|
||||
m_pInternal->m_func_onComplete(hrResultAll);
|
||||
|
||||
@ -41,11 +41,14 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <regex>
|
||||
#include <atomic>
|
||||
|
||||
namespace NSNetwork
|
||||
{
|
||||
namespace NSFileTransport
|
||||
{
|
||||
pid_t pid;
|
||||
std::atomic<bool>* m_isExit;
|
||||
std::string wget_url_validate(const std::string& url)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
@ -58,9 +61,10 @@ namespace NSNetwork
|
||||
return url.substr(pos);
|
||||
}
|
||||
|
||||
int download_external(const std::wstring& sUrl, const std::wstring& sOutput, std::function<void(int)> func_onProgress)
|
||||
int download_external(const std::wstring& sUrl, const std::wstring& sOutput, std::function<void(int)> func_onProgress, std::atomic<bool>* isExit)
|
||||
{
|
||||
int nReturnCode = -1;
|
||||
m_isExit = isExit;
|
||||
std::string sUrlA = U_TO_UTF8(sUrl);
|
||||
//sUrlA =("\"" + sUrlA + "\"");
|
||||
std::string sOutputA = U_TO_UTF8(sOutput);
|
||||
@ -72,7 +76,7 @@ namespace NSNetwork
|
||||
if(func_onProgress)
|
||||
pipe(pipefd);
|
||||
|
||||
pid_t pid = fork(); // create child process
|
||||
pid = fork(); // create child process
|
||||
int status;
|
||||
|
||||
switch (pid)
|
||||
@ -116,13 +120,27 @@ namespace NSNetwork
|
||||
default: // parent process, pid now contains the child pid
|
||||
if(func_onProgress)
|
||||
{
|
||||
close(pipefd[1]);
|
||||
// close the write end of the pipe in the parent
|
||||
size_t size = 81;
|
||||
char buffer[size];
|
||||
std::string str;
|
||||
close(pipefd[1]); // close the write end of the pipe in the parent
|
||||
ssize_t res = 1;
|
||||
std::regex r(R"(\d+(?:\.\d+)?%)");
|
||||
std::smatch sm;
|
||||
std::string percentFull;
|
||||
std::string percent;
|
||||
int percentInt;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if(m_isExit->load())
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
//while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
|
||||
return nReturnCode;
|
||||
}
|
||||
|
||||
str.clear();
|
||||
res = read(pipefd[0], buffer, sizeof(buffer));
|
||||
|
||||
@ -131,15 +149,11 @@ namespace NSNetwork
|
||||
|
||||
str.append(buffer);
|
||||
|
||||
std::regex r(R"(\d+(?:\.\d+)?%)");
|
||||
std::smatch sm;
|
||||
std::string percentFull;
|
||||
std::string percent;
|
||||
if(regex_search(str, sm, r))
|
||||
{
|
||||
percentFull = sm.str();
|
||||
percent = percentFull.substr(0, percentFull.find("."));
|
||||
int percentInt = std::stoi(percent);
|
||||
percentInt = std::stoi(percent);
|
||||
|
||||
if(percentInt >= 0 && percentInt <= 100)
|
||||
func_onProgress(percentInt);
|
||||
@ -147,14 +161,28 @@ namespace NSNetwork
|
||||
|
||||
if(str.find("100.0%") != std::string::npos)
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
nReturnCode = WEXITSTATUS(status);
|
||||
else {
|
||||
int waitres;
|
||||
while (1) // wait for child to complete
|
||||
{
|
||||
if(m_isExit->load())
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
return nReturnCode;
|
||||
}
|
||||
else if((waitres = waitpid(pid, &status, WNOHANG)) > 0)
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
nReturnCode = WEXITSTATUS(status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +190,7 @@ namespace NSNetwork
|
||||
{
|
||||
std::string sUrlValidateA = wget_url_validate(sUrlA);
|
||||
|
||||
pid_t pid = fork(); // create child process
|
||||
pid = fork(); // create child process
|
||||
int status;
|
||||
|
||||
switch (pid)
|
||||
@ -191,12 +219,23 @@ namespace NSNetwork
|
||||
break;
|
||||
}
|
||||
default: // parent process, pid now contains the child pid
|
||||
while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
|
||||
if (WIFEXITED(status))
|
||||
int waitres;
|
||||
while (1) // wait for child to complete
|
||||
{
|
||||
nReturnCode = WEXITSTATUS(status);
|
||||
if(m_isExit->load())
|
||||
{
|
||||
kill(pid, SIGTERM);
|
||||
return nReturnCode;
|
||||
}
|
||||
else if((waitres = waitpid(pid, &status, WNOHANG)) > 0)
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
nReturnCode = WEXITSTATUS(status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user