mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2025-01-23 22:08:24 +00:00
Strictly reviewed the exclusive control of PseudoFdInfo class
This commit is contained in:
parent
3e242d0bad
commit
f6d7ff1084
@ -131,6 +131,8 @@ PseudoFdInfo::PseudoFdInfo(int fd, int open_flags) : pseudo_fd(-1), physical_fd(
|
|||||||
|
|
||||||
PseudoFdInfo::~PseudoFdInfo()
|
PseudoFdInfo::~PseudoFdInfo()
|
||||||
{
|
{
|
||||||
|
Clear(); // call before destrying the mutex
|
||||||
|
|
||||||
if(is_lock_init){
|
if(is_lock_init){
|
||||||
int result;
|
int result;
|
||||||
if(0 != (result = pthread_mutex_destroy(&upload_list_lock))){
|
if(0 != (result = pthread_mutex_destroy(&upload_list_lock))){
|
||||||
@ -139,25 +141,25 @@ PseudoFdInfo::~PseudoFdInfo()
|
|||||||
}
|
}
|
||||||
is_lock_init = false;
|
is_lock_init = false;
|
||||||
}
|
}
|
||||||
Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PseudoFdInfo::Clear()
|
bool PseudoFdInfo::Clear()
|
||||||
{
|
{
|
||||||
|
CancelAllThreads();
|
||||||
|
CloseUploadFd();
|
||||||
|
|
||||||
if(-1 != pseudo_fd){
|
if(-1 != pseudo_fd){
|
||||||
PseudoFdManager::Release(pseudo_fd);
|
PseudoFdManager::Release(pseudo_fd);
|
||||||
}
|
}
|
||||||
pseudo_fd = -1;
|
pseudo_fd = -1;
|
||||||
physical_fd = -1;
|
physical_fd = -1;
|
||||||
|
|
||||||
CloseUploadFd(AutoLock::ALREADY_LOCKED); // [NOTE] already destroy mutex, then do not lock it.
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PseudoFdInfo::CloseUploadFd(AutoLock::Type type)
|
void PseudoFdInfo::CloseUploadFd()
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(&upload_list_lock, type);
|
AutoLock auto_lock(&upload_list_lock);
|
||||||
|
|
||||||
if(-1 != upload_fd){
|
if(-1 != upload_fd){
|
||||||
close(upload_fd);
|
close(upload_fd);
|
||||||
@ -227,17 +229,20 @@ bool PseudoFdInfo::Readable() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PseudoFdInfo::ClearUploadInfo(bool is_cancel_mp, AutoLock::Type type)
|
bool PseudoFdInfo::ClearUploadInfo(bool is_cancel_mp)
|
||||||
|
{
|
||||||
|
if(is_cancel_mp){
|
||||||
|
if(!CancelAllThreads()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ResetUploadInfo(AutoLock::NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PseudoFdInfo::ResetUploadInfo(AutoLock::Type type)
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(&upload_list_lock, type);
|
AutoLock auto_lock(&upload_list_lock, type);
|
||||||
|
|
||||||
if(is_cancel_mp){
|
|
||||||
// [TODO]
|
|
||||||
// If processing for cancellation is required, it will be processed here. Not implemented yet.
|
|
||||||
//
|
|
||||||
S3FS_PRN_DBG("If processing for cancellation is required, it will be processed here.");
|
|
||||||
}
|
|
||||||
|
|
||||||
upload_id.erase();
|
upload_id.erase();
|
||||||
upload_list.clear();
|
upload_list.clear();
|
||||||
instruct_count = 0;
|
instruct_count = 0;
|
||||||
@ -247,13 +252,24 @@ bool PseudoFdInfo::ClearUploadInfo(bool is_cancel_mp, AutoLock::Type type)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PseudoFdInfo::InitialUploadInfo(const std::string& id, AutoLock::Type type)
|
bool PseudoFdInfo::RowInitialUploadInfo(const std::string& id, bool is_cancel_mp, AutoLock::Type type)
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(&upload_list_lock, type);
|
if(is_cancel_mp && AutoLock::ALREADY_LOCKED == type){
|
||||||
|
S3FS_PRN_ERR("Internal Error: Could not call this with type=AutoLock::ALREADY_LOCKED and is_cancel_mp=true");
|
||||||
if(!ClearUploadInfo(true, AutoLock::ALREADY_LOCKED)){
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(is_cancel_mp){
|
||||||
|
if(!ClearUploadInfo(is_cancel_mp)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(!ResetUploadInfo(type)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoLock auto_lock(&upload_list_lock, type);
|
||||||
upload_id = id;
|
upload_id = id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -553,7 +569,7 @@ ssize_t PseudoFdInfo::UploadBoundaryLastUntreatedArea(const char* path, headers_
|
|||||||
S3FS_PRN_ERR("failed to setup multipart upload(create upload id) by errno(%d)", result);
|
S3FS_PRN_ERR("failed to setup multipart upload(create upload id) by errno(%d)", result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if(!InitialUploadInfo(tmp_upload_id, AutoLock::ALREADY_LOCKED)){
|
if(!RowInitialUploadInfo(tmp_upload_id, false/* not need to cancel */, AutoLock::ALREADY_LOCKED)){
|
||||||
S3FS_PRN_ERR("failed to setup multipart upload(set upload id to object)");
|
S3FS_PRN_ERR("failed to setup multipart upload(set upload id to object)");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -593,23 +609,17 @@ ssize_t PseudoFdInfo::UploadBoundaryLastUntreatedArea(const char* path, headers_
|
|||||||
|
|
||||||
int PseudoFdInfo::WaitAllThreadsExit()
|
int PseudoFdInfo::WaitAllThreadsExit()
|
||||||
{
|
{
|
||||||
while(true){
|
int result;
|
||||||
|
bool is_loop = true;
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(&upload_list_lock);
|
AutoLock auto_lock(&upload_list_lock);
|
||||||
if(0 == instruct_count && 0 == completed_count){
|
if(0 == instruct_count && 0 == completed_count){
|
||||||
break;
|
result = last_result;
|
||||||
}
|
is_loop = false;
|
||||||
|
|
||||||
while(uploaded_sem.try_wait()){
|
|
||||||
if(0 < completed_count){
|
|
||||||
--completed_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(0 == instruct_count && 0 == completed_count){
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(is_loop){
|
||||||
// need to wait the worker exiting
|
// need to wait the worker exiting
|
||||||
uploaded_sem.wait();
|
uploaded_sem.wait();
|
||||||
{
|
{
|
||||||
@ -617,15 +627,32 @@ int PseudoFdInfo::WaitAllThreadsExit()
|
|||||||
if(0 < completed_count){
|
if(0 < completed_count){
|
||||||
--completed_count;
|
--completed_count;
|
||||||
}
|
}
|
||||||
|
if(0 == instruct_count && 0 == completed_count){
|
||||||
|
// break loop
|
||||||
|
result = last_result;
|
||||||
|
is_loop = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PseudoFdInfo::CancelAllThreads()
|
||||||
|
{
|
||||||
|
bool need_cancel = false;
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(&upload_list_lock);
|
AutoLock auto_lock(&upload_list_lock);
|
||||||
result = last_result;
|
if(0 < instruct_count && 0 < completed_count){
|
||||||
|
S3FS_PRN_INFO("The upload thread is running, so cancel them and wait for the end.");
|
||||||
|
need_cancel = true;
|
||||||
|
last_result = -ECANCELED; // to stop thread running
|
||||||
}
|
}
|
||||||
return result;
|
}
|
||||||
|
if(need_cancel){
|
||||||
|
WaitAllThreadsExit();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -76,12 +76,15 @@ class PseudoFdInfo
|
|||||||
static void* MultipartUploadThreadWorker(void* arg);
|
static void* MultipartUploadThreadWorker(void* arg);
|
||||||
|
|
||||||
bool Clear();
|
bool Clear();
|
||||||
void CloseUploadFd(AutoLock::Type type = AutoLock::NONE);
|
void CloseUploadFd();
|
||||||
bool OpenUploadFd(AutoLock::Type type = AutoLock::NONE);
|
bool OpenUploadFd(AutoLock::Type type = AutoLock::NONE);
|
||||||
|
bool ResetUploadInfo(AutoLock::Type type);
|
||||||
|
bool RowInitialUploadInfo(const std::string& id, bool is_cancel_mp, AutoLock::Type type);
|
||||||
bool CompleteInstruction(int result, AutoLock::Type type = AutoLock::NONE);
|
bool CompleteInstruction(int result, AutoLock::Type type = AutoLock::NONE);
|
||||||
bool ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy, AutoLock::Type type = AutoLock::NONE);
|
bool ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy, AutoLock::Type type = AutoLock::NONE);
|
||||||
bool InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag, AutoLock::Type type = AutoLock::NONE);
|
bool InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag, AutoLock::Type type = AutoLock::NONE);
|
||||||
int WaitAllThreadsExit();
|
int WaitAllThreadsExit();
|
||||||
|
bool CancelAllThreads();
|
||||||
bool ExtractUploadPartsFromUntreatedArea(off_t& untreated_start, off_t& untreated_size, mp_part_list_t& to_upload_list, filepart_list_t& cancel_upload_list, off_t max_mp_size);
|
bool ExtractUploadPartsFromUntreatedArea(off_t& untreated_start, off_t& untreated_size, mp_part_list_t& to_upload_list, filepart_list_t& cancel_upload_list, off_t max_mp_size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -95,8 +98,8 @@ class PseudoFdInfo
|
|||||||
bool Readable() const;
|
bool Readable() const;
|
||||||
|
|
||||||
bool Set(int fd, int open_flags);
|
bool Set(int fd, int open_flags);
|
||||||
bool ClearUploadInfo(bool is_clear_part = false, AutoLock::Type type = AutoLock::NONE);
|
bool ClearUploadInfo(bool is_cancel_mp = false);
|
||||||
bool InitialUploadInfo(const std::string& id, AutoLock::Type type = AutoLock::NONE);
|
bool InitialUploadInfo(const std::string& id){ return RowInitialUploadInfo(id, true, AutoLock::NONE); }
|
||||||
|
|
||||||
bool IsUploading() const { return !upload_id.empty(); }
|
bool IsUploading() const { return !upload_id.empty(); }
|
||||||
bool GetUploadId(std::string& id) const;
|
bool GetUploadId(std::string& id) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user