Convert pthread_mutex to std::mutex (#2476)

This simplifies resource management and improve Windows compatibility.
This commit is contained in:
Andrew Gaul 2024-06-23 21:18:01 +05:30 committed by GitHub
parent 86b353511a
commit 622dc0a815
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 219 additions and 781 deletions

View File

@ -54,7 +54,6 @@ s3fs_SOURCES = \
fdcache_untreated.cpp \
addhead.cpp \
sighandlers.cpp \
autolock.cpp \
threadpoolman.cpp \
common_auth.cpp
if USE_SSL_OPENSSL

View File

@ -1,78 +0,0 @@
/*
* s3fs - FUSE-based file system backed by Amazon S3
*
* Copyright(C) 2007 Takeshi Nakatani <ggtakec.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cstdlib>
#include <cerrno>
#include "autolock.h"
#include "s3fs_logger.h"
//-------------------------------------------------------------------
// Class AutoLock
//-------------------------------------------------------------------
AutoLock::AutoLock(pthread_mutex_t* pmutex, Type type) : auto_mutex(pmutex)
{
if (type == ALREADY_LOCKED) {
is_lock_acquired = false;
} else if (type == NO_WAIT) {
int result = pthread_mutex_trylock(auto_mutex);
if(result == 0){
is_lock_acquired = true;
}else if(result == EBUSY){
is_lock_acquired = false;
}else{
S3FS_PRN_CRIT("pthread_mutex_trylock returned: %d", result);
abort();
}
} else {
int result = pthread_mutex_lock(auto_mutex);
if(result == 0){
is_lock_acquired = true;
}else{
S3FS_PRN_CRIT("pthread_mutex_lock returned: %d", result);
abort();
}
}
}
bool AutoLock::isLockAcquired() const
{
return is_lock_acquired;
}
AutoLock::~AutoLock()
{
if (is_lock_acquired) {
int result = pthread_mutex_unlock(auto_mutex);
if(result != 0){
S3FS_PRN_CRIT("pthread_mutex_unlock returned: %d", result);
abort();
}
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: expandtab sw=4 ts=4 fdm=marker
* vim<600: expandtab sw=4 ts=4
*/

View File

@ -1,67 +0,0 @@
/*
* s3fs - FUSE-based file system backed by Amazon S3
*
* Copyright(C) 2007 Randy Rizun <rrizun@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef S3FS_AUTOLOCK_H_
#define S3FS_AUTOLOCK_H_
#include <cstdint>
#include <pthread.h>
// empty annotation to indicate lock requirement
#define REQUIRES(...)
//-------------------------------------------------------------------
// AutoLock Class
//-------------------------------------------------------------------
class AutoLock
{
public:
enum Type : uint8_t {
NO_WAIT = 1,
ALREADY_LOCKED = 2,
NONE = 0
};
private:
pthread_mutex_t* const auto_mutex;
bool is_lock_acquired;
private:
AutoLock(const AutoLock&) = delete;
AutoLock(AutoLock&&) = delete;
AutoLock& operator=(const AutoLock&) = delete;
AutoLock& operator=(AutoLock&&) = delete;
public:
explicit AutoLock(pthread_mutex_t* pmutex, Type type = NONE);
~AutoLock();
bool isLockAcquired() const;
};
#endif // S3FS_AUTOLOCK_H_
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: expandtab sw=4 ts=4 fdm=marker
* vim<600: expandtab sw=4 ts=4
*/

View File

@ -28,7 +28,6 @@
#include "s3fs_logger.h"
#include "s3fs_util.h"
#include "cache.h"
#include "autolock.h"
#include "string_util.h"
//-------------------------------------------------------------------
@ -118,7 +117,7 @@ struct sort_symlinkiterlist{
// Static
//-------------------------------------------------------------------
StatCache StatCache::singleton;
pthread_mutex_t StatCache::stat_cache_lock;
std::mutex StatCache::stat_cache_lock;
//-------------------------------------------------------------------
// Constructor/Destructor
@ -127,16 +126,6 @@ StatCache::StatCache() : IsExpireTime(true), IsExpireIntervalType(false), Expire
{
if(this == StatCache::getStatCacheData()){
stat_cache.clear();
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&StatCache::stat_cache_lock, &attr))){
S3FS_PRN_CRIT("failed to init stat_cache_lock: %d", result);
abort();
}
}else{
abort();
}
@ -146,11 +135,6 @@ StatCache::~StatCache()
{
if(this == StatCache::getStatCacheData()){
Clear();
int result = pthread_mutex_destroy(&StatCache::stat_cache_lock);
if(result != 0){
S3FS_PRN_CRIT("failed to destroy stat_cache_lock: %d", result);
abort();
}
}else{
abort();
}
@ -203,7 +187,7 @@ bool StatCache::SetCacheNoObject(bool flag)
void StatCache::Clear()
{
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
stat_cache.clear();
S3FS_MALLOCTRIM(0);
@ -214,7 +198,7 @@ bool StatCache::GetStat(const std::string& key, struct stat* pst, headers_t* met
bool is_delete_cache = false;
std::string strpath = key;
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
stat_cache_t::iterator iter = stat_cache.end();
if(overcheck && '/' != *strpath.rbegin()){
@ -300,7 +284,7 @@ bool StatCache::IsNoObjectCache(const std::string& key, bool overcheck)
return false;
}
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
stat_cache_t::iterator iter = stat_cache.end();
if(overcheck && '/' != *strpath.rbegin()){
@ -339,7 +323,7 @@ bool StatCache::AddStat(const std::string& key, const headers_t& meta, bool forc
}
S3FS_PRN_INFO3("add stat cache entry[path=%s]", key.c_str());
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
if(stat_cache.end() != stat_cache.find(key)){
// found cache
@ -416,7 +400,7 @@ bool StatCache::UpdateMetaStats(const std::string& key, const headers_t& meta)
}
S3FS_PRN_INFO3("update stat cache entry[path=%s]", key.c_str());
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
stat_cache_t::iterator iter = stat_cache.find(key);
if(stat_cache.end() == iter){
return true;
@ -459,7 +443,7 @@ bool StatCache::AddNoObjectCache(const std::string& key)
}
S3FS_PRN_INFO3("add no object cache entry[path=%s]", key.c_str());
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
if(stat_cache.end() != stat_cache.find(key)){
// found
@ -496,7 +480,7 @@ bool StatCache::AddNoObjectCache(const std::string& key)
void StatCache::ChangeNoTruncateFlag(const std::string& key, bool no_truncate)
{
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
stat_cache_t::iterator iter = stat_cache.find(key);
if(stat_cache.end() != iter){
@ -608,7 +592,7 @@ bool StatCache::GetSymlink(const std::string& key, std::string& value)
bool is_delete_cache = false;
const std::string& strpath = key;
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
symlink_cache_t::iterator iter = symlink_cache.find(strpath);
if(iter != symlink_cache.end()){
@ -644,7 +628,7 @@ bool StatCache::AddSymlink(const std::string& key, const std::string& value)
}
S3FS_PRN_INFO3("add symbolic link cache entry[path=%s, value=%s]", key.c_str(), value.c_str());
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
if(symlink_cache.end() != symlink_cache.find(key)){
// found
@ -819,7 +803,7 @@ bool StatCache::GetNotruncateCache(const std::string& parentdir, notruncate_file
dirpath += '/';
}
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
notruncate_dir_map_t::iterator iter = notruncate_file_cache.find(dirpath);
if(iter == notruncate_file_cache.end()){

View File

@ -23,11 +23,12 @@
#include <cstring>
#include <map>
#include <mutex>
#include <string>
#include <sys/stat.h>
#include <vector>
#include "autolock.h"
#include "common.h"
#include "metaheader.h"
//-------------------------------------------------------------------
@ -81,7 +82,7 @@ class StatCache
{
private:
static StatCache singleton;
static pthread_mutex_t stat_cache_lock;
static std::mutex stat_cache_lock;
stat_cache_t stat_cache;
bool IsExpireTime;
bool IsExpireIntervalType; // if this flag is true, cache data is updated at last access time.
@ -178,7 +179,7 @@ class StatCache
// Delete stat cache
bool DelStat(const std::string& key)
{
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
return DelStatHasLock(key);
}
bool DelStatHasLock(const std::string& key) REQUIRES(StatCache::stat_cache_lock);
@ -187,7 +188,7 @@ class StatCache
bool GetSymlink(const std::string& key, std::string& value);
bool AddSymlink(const std::string& key, const std::string& value);
bool DelSymlink(const std::string& key) {
AutoLock lock(&StatCache::stat_cache_lock);
const std::lock_guard<std::mutex> lock(StatCache::stat_cache_lock);
return DelSymlinkHasLock(key);
}
bool DelSymlinkHasLock(const std::string& key);

View File

@ -51,6 +51,9 @@ extern std::string instance_name;
//-------------------------------------------------------------------
#define S3FS_FUNCATTR_WEAK __attribute__ ((weak,unused))
// empty annotation to indicate lock requirement
#define REQUIRES(...)
#endif // S3FS_COMMON_H_
/*

View File

@ -35,7 +35,6 @@
#include "curl_multi.h"
#include "curl_util.h"
#include "s3fs_auth.h"
#include "autolock.h"
#include "curl_handlerpool.h"
#include "s3fs_cred.h"
#include "s3fs_util.h"
@ -84,8 +83,8 @@ static constexpr char SPECIAL_DARWIN_MIME_FILE[] = "/etc/apache2/mime.typ
// Class S3fsCurl
//-------------------------------------------------------------------
constexpr char S3fsCurl::S3FS_SSL_PRIVKEY_PASSWORD[];
pthread_mutex_t S3fsCurl::curl_warnings_lock;
pthread_mutex_t S3fsCurl::curl_handles_lock;
std::mutex S3fsCurl::curl_warnings_lock;
std::mutex S3fsCurl::curl_handles_lock;
S3fsCurl::callback_locks_t S3fsCurl::callback_locks;
bool S3fsCurl::is_initglobal_done = false;
CurlHandlerPool* S3fsCurl::sCurlPool = nullptr;
@ -144,23 +143,6 @@ long S3fsCurl::ipresolve_type = CURL_IPRESOLVE_WHATEVER;
//-------------------------------------------------------------------
bool S3fsCurl::InitS3fsCurl()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
if(0 != pthread_mutex_init(&S3fsCurl::curl_warnings_lock, &attr)){
return false;
}
if(0 != pthread_mutex_init(&S3fsCurl::curl_handles_lock, &attr)){
return false;
}
if(0 != pthread_mutex_init(&S3fsCurl::callback_locks.dns, &attr)){
return false;
}
if(0 != pthread_mutex_init(&S3fsCurl::callback_locks.ssl_session, &attr)){
return false;
}
if(!S3fsCurl::InitGlobalCurl()){
return false;
}
@ -199,18 +181,6 @@ bool S3fsCurl::DestroyS3fsCurl()
if(!S3fsCurl::DestroyGlobalCurl()){
result = false;
}
if(0 != pthread_mutex_destroy(&S3fsCurl::callback_locks.dns)){
result = false;
}
if(0 != pthread_mutex_destroy(&S3fsCurl::callback_locks.ssl_session)){
result = false;
}
if(0 != pthread_mutex_destroy(&S3fsCurl::curl_handles_lock)){
result = false;
}
if(0 != pthread_mutex_destroy(&S3fsCurl::curl_warnings_lock)){
result = false;
}
return result;
}
@ -308,17 +278,10 @@ void S3fsCurl::LockCurlShare(CURL* handle, curl_lock_data nLockData, curl_lock_a
return;
}
S3fsCurl::callback_locks_t* locks = static_cast<S3fsCurl::callback_locks_t*>(useptr);
int result;
if(CURL_LOCK_DATA_DNS == nLockData){
if(0 != (result = pthread_mutex_lock(&locks->dns))){
S3FS_PRN_CRIT("pthread_mutex_lock returned: %d", result);
abort();
}
locks->dns.lock();
}else if(CURL_LOCK_DATA_SSL_SESSION == nLockData){
if(0 != (result = pthread_mutex_lock(&locks->ssl_session))){
S3FS_PRN_CRIT("pthread_mutex_lock returned: %d", result);
abort();
}
locks->ssl_session.lock();
}
}
@ -328,17 +291,10 @@ void S3fsCurl::UnlockCurlShare(CURL* handle, curl_lock_data nLockData, void* use
return;
}
S3fsCurl::callback_locks_t* locks = static_cast<S3fsCurl::callback_locks_t*>(useptr);
int result;
if(CURL_LOCK_DATA_DNS == nLockData){
if(0 != (result = pthread_mutex_unlock(&locks->dns))){
S3FS_PRN_CRIT("pthread_mutex_unlock returned: %d", result);
abort();
}
locks->dns.unlock();
}else if(CURL_LOCK_DATA_SSL_SESSION == nLockData){
if(0 != (result = pthread_mutex_unlock(&locks->ssl_session))){
S3FS_PRN_CRIT("pthread_mutex_unlock returned: %d", result);
abort();
}
locks->ssl_session.unlock();
}
}
@ -359,7 +315,7 @@ int S3fsCurl::CurlProgress(void *clientp, double dltotal, double dlnow, double u
time_t now = time(nullptr);
progress_t p(dlnow, ulnow);
AutoLock lock(&S3fsCurl::curl_handles_lock);
const std::lock_guard<std::mutex> lock(S3fsCurl::curl_handles_lock);
// any progress?
if(p != S3fsCurl::curl_progress[curl]){
@ -2006,7 +1962,7 @@ bool S3fsCurl::ResetHandle()
{
bool run_once;
{
AutoLock lock(&S3fsCurl::curl_warnings_lock);
const std::lock_guard<std::mutex> lock(S3fsCurl::curl_warnings_lock);
run_once = curl_warnings_once;
curl_warnings_once = true;
}
@ -2137,7 +2093,7 @@ bool S3fsCurl::ResetHandle()
bool S3fsCurl::CreateCurlHandle(bool only_pool, bool remake)
{
AutoLock lock(&S3fsCurl::curl_handles_lock);
const std::lock_guard<std::mutex> lock(S3fsCurl::curl_handles_lock);
if(hCurl && remake){
if(!DestroyCurlHandleHasLock(false, true)){
@ -2167,7 +2123,7 @@ bool S3fsCurl::CreateCurlHandle(bool only_pool, bool remake)
bool S3fsCurl::DestroyCurlHandle(bool restore_pool, bool clear_internal_data)
{
AutoLock lock(&S3fsCurl::curl_handles_lock);
const std::lock_guard<std::mutex> lock(S3fsCurl::curl_handles_lock);
return DestroyCurlHandleHasLock(restore_pool, clear_internal_data);
}
@ -2300,7 +2256,7 @@ bool S3fsCurl::RemakeHandle()
// reset handle
{
AutoLock lock(&S3fsCurl::curl_handles_lock);
const std::lock_guard<std::mutex> lock(S3fsCurl::curl_handles_lock);
ResetHandle();
}
@ -2738,7 +2694,7 @@ int S3fsCurl::RequestPerform(bool dontAddAuthHeaders /*=false*/)
S3FS_PRN_ERR("### CURLE_ABORTED_BY_CALLBACK");
sleep(4);
{
AutoLock lock(&S3fsCurl::curl_handles_lock);
const std::lock_guard<std::mutex> lock(S3fsCurl::curl_handles_lock);
S3fsCurl::curl_times[hCurl] = time(nullptr);
}
break;

View File

@ -25,10 +25,11 @@
#include <curl/curl.h>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "autolock.h"
#include "common.h"
#include "fdcache_page.h"
#include "metaheader.h"
#include "types.h"
@ -117,12 +118,12 @@ class S3fsCurl
static constexpr char S3FS_SSL_PRIVKEY_PASSWORD[] = "S3FS_SSL_PRIVKEY_PASSWORD";
// class variables
static pthread_mutex_t curl_warnings_lock;
static std::mutex curl_warnings_lock;
static bool curl_warnings_once; // emit older curl warnings only once
static pthread_mutex_t curl_handles_lock;
static std::mutex curl_handles_lock;
static struct callback_locks_t {
pthread_mutex_t dns;
pthread_mutex_t ssl_session;
std::mutex dns;
std::mutex ssl_session;
} callback_locks;
static bool is_initglobal_done;
static CurlHandlerPool* sCurlPool;
@ -199,7 +200,7 @@ class S3fsCurl
std::string op; // the HTTP verb of the request ("PUT", "GET", etc.)
std::string query_string; // request query string
Semaphore *sem;
pthread_mutex_t *completed_tids_lock;
std::mutex *completed_tids_lock;
std::vector<pthread_t> *completed_tids;
s3fscurl_lazy_setup fpLazySetup; // curl options for lazy setting function
CURLcode curlCode; // handle curl return
@ -261,7 +262,7 @@ class S3fsCurl
static int RawCurlDebugFunc(const CURL* hcurl, curl_infotype type, char* data, size_t size, void* userptr, curl_infotype datatype);
// methods
bool ResetHandle() REQUIRES(&S3fsCurl::curl_handles_lock);
bool ResetHandle() REQUIRES(S3fsCurl::curl_handles_lock);
bool RemakeHandle();
bool ClearInternalData();
void insertV4Headers(const std::string& access_key_id, const std::string& secret_access_key, const std::string& access_token);

View File

@ -22,23 +22,12 @@
#include "s3fs_logger.h"
#include "curl_handlerpool.h"
#include "autolock.h"
//-------------------------------------------------------------------
// Class CurlHandlerPool
//-------------------------------------------------------------------
bool CurlHandlerPool::Init()
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
if (0 != pthread_mutex_init(&mLock, &attr)) {
S3FS_PRN_ERR("Init curl handlers lock failed");
return false;
}
for(int cnt = 0; cnt < mMaxHandlers; ++cnt){
CURL* hCurl = curl_easy_init();
if(!hCurl){
@ -53,27 +42,21 @@ bool CurlHandlerPool::Init()
bool CurlHandlerPool::Destroy()
{
{
AutoLock lock(&mLock);
const std::lock_guard<std::mutex> lock(mLock);
while(!mPool.empty()){
CURL* hCurl = mPool.back();
mPool.pop_back();
if(hCurl){
curl_easy_cleanup(hCurl);
}
while(!mPool.empty()){
CURL* hCurl = mPool.back();
mPool.pop_back();
if(hCurl){
curl_easy_cleanup(hCurl);
}
}
if (0 != pthread_mutex_destroy(&mLock)) {
S3FS_PRN_ERR("Destroy curl handlers lock failed");
return false;
}
return true;
}
CURL* CurlHandlerPool::GetHandler(bool only_pool)
{
AutoLock lock(&mLock);
const std::lock_guard<std::mutex> lock(mLock);
CURL* hCurl = nullptr;
@ -97,7 +80,7 @@ void CurlHandlerPool::ReturnHandler(CURL* hCurl, bool restore_pool)
if(!hCurl){
return;
}
AutoLock lock(&mLock);
const std::lock_guard<std::mutex> lock(mLock);
if(restore_pool){
S3FS_PRN_DBG("Return handler to pool");
@ -122,7 +105,7 @@ void CurlHandlerPool::ResetHandler(CURL* hCurl)
if(!hCurl){
return;
}
AutoLock lock(&mLock);
const std::lock_guard<std::mutex> lock(mLock);
curl_easy_reset(hCurl);
}

View File

@ -24,6 +24,7 @@
#include <cassert>
#include <curl/curl.h>
#include <list>
#include <mutex>
//----------------------------------------------
// Typedefs
@ -54,7 +55,7 @@ class CurlHandlerPool
private:
int mMaxHandlers;
pthread_mutex_t mLock;
std::mutex mLock;
hcurllist_t mPool;
};

View File

@ -27,7 +27,6 @@
#include "s3fs_logger.h"
#include "curl_multi.h"
#include "curl.h"
#include "autolock.h"
#include "psemaphore.h"
//-------------------------------------------------------------------
@ -35,25 +34,11 @@
//-------------------------------------------------------------------
S3fsMultiCurl::S3fsMultiCurl(int maxParallelism, bool not_abort) : maxParallelism(maxParallelism), not_abort(not_abort), SuccessCallback(nullptr), NotFoundCallback(nullptr), RetryCallback(nullptr), pSuccessCallbackParam(nullptr), pNotFoundCallbackParam(nullptr)
{
int result;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
if (0 != (result = pthread_mutex_init(&completed_tids_lock, &attr))) {
S3FS_PRN_ERR("could not initialize completed_tids_lock: %i", result);
abort();
}
}
S3fsMultiCurl::~S3fsMultiCurl()
{
Clear();
int result;
if(0 != (result = pthread_mutex_destroy(&completed_tids_lock))){
S3FS_PRN_ERR("could not destroy completed_tids_lock: %i", result);
}
}
bool S3fsMultiCurl::ClearEx(bool is_all)
@ -143,7 +128,7 @@ int S3fsMultiCurl::MultiPerform()
sem.wait();
{
AutoLock lock(&completed_tids_lock);
const std::lock_guard<std::mutex> lock(completed_tids_lock);
for(std::vector<pthread_t>::iterator it = completed_tids.begin(); it != completed_tids.end(); ++it){
void* retval;
@ -179,7 +164,7 @@ int S3fsMultiCurl::MultiPerform()
sem.wait();
}
AutoLock lock(&completed_tids_lock);
const std::lock_guard<std::mutex> lock(completed_tids_lock);
for (std::vector<pthread_t>::iterator titer = completed_tids.begin(); titer != completed_tids.end(); ++titer) {
void* retval;
@ -377,7 +362,7 @@ void* S3fsMultiCurl::RequestPerformWrapper(void* arg)
s3fscurl->DestroyCurlHandle(true, false);
}
AutoLock lock(s3fscurl->completed_tids_lock);
const std::lock_guard<std::mutex> lock(*s3fscurl->completed_tids_lock);
s3fscurl->completed_tids->push_back(pthread_self());
s3fscurl->sem->post();

View File

@ -22,6 +22,7 @@
#define S3FS_CURL_MULTI_H_
#include <memory>
#include <mutex>
#include <vector>
//----------------------------------------------
@ -52,7 +53,7 @@ class S3fsMultiCurl
void* pSuccessCallbackParam;
void* pNotFoundCallbackParam;
pthread_mutex_t completed_tids_lock;
std::mutex completed_tids_lock;
std::vector<pthread_t> completed_tids;
private:

View File

@ -33,7 +33,6 @@
#include "s3fs_logger.h"
#include "s3fs_cred.h"
#include "string_util.h"
#include "autolock.h"
//
// The following symbols are used by FdManager::RawCheckAllCache().
@ -76,10 +75,9 @@ static constexpr char NOCACHE_PATH_PREFIX_FORM[] = " __S3FS_UNEXISTED_PATH_%lx__
// FdManager class variable
//------------------------------------------------
FdManager FdManager::singleton;
pthread_mutex_t FdManager::fd_manager_lock;
pthread_mutex_t FdManager::cache_cleanup_lock;
pthread_mutex_t FdManager::reserved_diskspace_lock;
bool FdManager::is_lock_init(false);
std::mutex FdManager::fd_manager_lock;
std::mutex FdManager::cache_cleanup_lock;
std::mutex FdManager::reserved_diskspace_lock;
std::string FdManager::cache_dir;
bool FdManager::check_cache_dir_exist(false);
off_t FdManager::free_disk_space = 0;
@ -240,13 +238,13 @@ bool FdManager::CheckCacheDirExist()
off_t FdManager::GetEnsureFreeDiskSpace()
{
AutoLock auto_lock(&FdManager::reserved_diskspace_lock);
const std::lock_guard<std::mutex> lock(FdManager::reserved_diskspace_lock);
return FdManager::free_disk_space;
}
off_t FdManager::SetEnsureFreeDiskSpace(off_t size)
{
AutoLock auto_lock(&FdManager::reserved_diskspace_lock);
const std::lock_guard<std::mutex> lock(FdManager::reserved_diskspace_lock);
off_t old = FdManager::free_disk_space;
FdManager::free_disk_space = size;
return old;
@ -429,7 +427,7 @@ FILE* FdManager::MakeTempFile() {
bool FdManager::HasOpenEntityFd(const char* path)
{
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
const FdEntity* ent;
int fd = -1;
@ -444,7 +442,7 @@ bool FdManager::HasOpenEntityFd(const char* path)
//
int FdManager::GetOpenFdCount(const char* path)
{
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
return FdManager::singleton.GetPseudoFdCount(path);
}
@ -454,27 +452,7 @@ int FdManager::GetOpenFdCount(const char* path)
//------------------------------------------------
FdManager::FdManager()
{
if(this == FdManager::get()){
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&FdManager::fd_manager_lock, &attr))){
S3FS_PRN_CRIT("failed to init fd_manager_lock: %d", result);
abort();
}
if(0 != (result = pthread_mutex_init(&FdManager::cache_cleanup_lock, &attr))){
S3FS_PRN_CRIT("failed to init cache_cleanup_lock: %d", result);
abort();
}
if(0 != (result = pthread_mutex_init(&FdManager::reserved_diskspace_lock, &attr))){
S3FS_PRN_CRIT("failed to init reserved_diskspace_lock: %d", result);
abort();
}
FdManager::is_lock_init = true;
}else{
if(this != FdManager::get()){
abort();
}
}
@ -487,23 +465,6 @@ FdManager::~FdManager()
S3FS_PRN_WARN("To exit with the cache file opened: path=%s, refcnt=%d", ent->GetPath().c_str(), ent->GetOpenCount());
}
fent.clear();
if(FdManager::is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&FdManager::fd_manager_lock))){
S3FS_PRN_CRIT("failed to destroy fd_manager_lock: %d", result);
abort();
}
if(0 != (result = pthread_mutex_destroy(&FdManager::cache_cleanup_lock))){
S3FS_PRN_CRIT("failed to destroy cache_cleanup_lock: %d", result);
abort();
}
if(0 != (result = pthread_mutex_destroy(&FdManager::reserved_diskspace_lock))){
S3FS_PRN_CRIT("failed to destroy reserved_diskspace_lock: %d", result);
abort();
}
FdManager::is_lock_init = false;
}
}else{
abort();
}
@ -571,7 +532,7 @@ FdEntity* FdManager::Open(int& fd, const char* path, const headers_t* pmeta, off
return nullptr;
}
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
// search in mapping by key(path)
fdent_map_t::iterator iter = fent.find(path);
@ -657,7 +618,7 @@ FdEntity* FdManager::GetExistFdEntity(const char* path, int existfd)
{
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d]", SAFESTRPTR(path), existfd);
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
// search from all entity.
for(fdent_map_t::iterator iter = fent.begin(); iter != fent.end(); ++iter){
@ -708,7 +669,7 @@ int FdManager::GetPseudoFdCount(const char* path)
void FdManager::Rename(const std::string &from, const std::string &to)
{
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
fdent_map_t::iterator iter = fent.find(from);
if(fent.end() == iter && !FdManager::IsCacheDir()){
@ -752,7 +713,7 @@ bool FdManager::Close(FdEntity* ent, int fd)
if(!ent || -1 == fd){
return true; // returns success
}
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
for(fdent_map_t::iterator iter = fent.begin(); iter != fent.end(); ++iter){
if(iter->second.get() == ent){
@ -778,7 +739,7 @@ bool FdManager::Close(FdEntity* ent, int fd)
bool FdManager::ChangeEntityToTempPath(const FdEntity* ent, const char* path)
{
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
for(fdent_map_t::iterator iter = fent.begin(); iter != fent.end(); ){
if(iter->second.get() == ent){
@ -803,16 +764,15 @@ void FdManager::CleanupCacheDir()
return;
}
AutoLock auto_lock_no_wait(&FdManager::cache_cleanup_lock, AutoLock::NO_WAIT);
if(auto_lock_no_wait.isLockAcquired()){
if(FdManager::cache_cleanup_lock.try_lock()){
//S3FS_PRN_DBG("cache cleanup started");
CleanupCacheDirInternal("");
//S3FS_PRN_DBG("cache cleanup ended");
}else{
// wait for other thread to finish cache cleanup
AutoLock auto_lock(&FdManager::cache_cleanup_lock);
FdManager::cache_cleanup_lock.lock();
}
FdManager::cache_cleanup_lock.unlock();
}
void FdManager::CleanupCacheDirInternal(const std::string &path)
@ -843,8 +803,7 @@ void FdManager::CleanupCacheDirInternal(const std::string &path)
if(S_ISDIR(st.st_mode)){
CleanupCacheDirInternal(next_path);
}else{
AutoLock auto_lock(&FdManager::fd_manager_lock, AutoLock::NO_WAIT);
if (!auto_lock.isLockAcquired()) {
if(!FdManager::fd_manager_lock.try_lock()){
S3FS_PRN_INFO("could not get fd_manager_lock when clean up file(%s), then skip it.", next_path.c_str());
continue;
}
@ -853,6 +812,7 @@ void FdManager::CleanupCacheDirInternal(const std::string &path)
S3FS_PRN_DBG("cleaned up: %s", next_path.c_str());
FdManager::DeleteCacheFile(next_path.c_str());
}
FdManager::fd_manager_lock.unlock();
}
}
closedir(dp);
@ -861,7 +821,7 @@ void FdManager::CleanupCacheDirInternal(const std::string &path)
bool FdManager::ReserveDiskSpace(off_t size)
{
if(IsSafeDiskSpace(nullptr, size)){
AutoLock auto_lock(&FdManager::reserved_diskspace_lock);
const std::lock_guard<std::mutex> lock(FdManager::reserved_diskspace_lock);
free_disk_space += size;
return true;
}
@ -870,7 +830,7 @@ bool FdManager::ReserveDiskSpace(off_t size)
void FdManager::FreeReservedDiskSpace(off_t size)
{
AutoLock auto_lock(&FdManager::reserved_diskspace_lock);
const std::lock_guard<std::mutex> lock(FdManager::reserved_diskspace_lock);
free_disk_space -= size;
}
@ -955,7 +915,7 @@ bool FdManager::RawCheckAllCache(FILE* fp, const char* cache_stat_top_dir, const
// check if the target file is currently in operation.
{
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
fdent_map_t::iterator iter = fent.find(object_file_path);
if(fent.end() != iter){

View File

@ -21,6 +21,9 @@
#ifndef S3FS_FDCACHE_H_
#define S3FS_FDCACHE_H_
#include <mutex>
#include "common.h"
#include "fdcache_entity.h"
//------------------------------------------------
@ -30,10 +33,9 @@ class FdManager
{
private:
static FdManager singleton;
static pthread_mutex_t fd_manager_lock;
static pthread_mutex_t cache_cleanup_lock;
static pthread_mutex_t reserved_diskspace_lock;
static bool is_lock_init;
static std::mutex fd_manager_lock;
static std::mutex cache_cleanup_lock;
static std::mutex reserved_diskspace_lock;
static std::string cache_dir;
static bool check_cache_dir_exist;
static off_t free_disk_space; // limit free disk space
@ -95,7 +97,7 @@ class FdManager
// Return FdEntity associated with path, returning nullptr on error. This operation increments the reference count; callers must decrement via Close after use.
FdEntity* GetFdEntity(const char* path, int& existfd, bool newfd = true) {
AutoLock auto_lock(&FdManager::fd_manager_lock);
const std::lock_guard<std::mutex> lock(FdManager::fd_manager_lock);
return GetFdEntityHasLock(path, existfd, newfd);
}
FdEntity* GetFdEntityHasLock(const char* path, int& existfd, bool newfd = true) REQUIRES(FdManager::fd_manager_lock);

View File

@ -23,7 +23,7 @@
#include <fcntl.h>
#include "autolock.h"
#include "common.h"
#include "metaheader.h"
class FdEntity;

View File

@ -34,7 +34,6 @@
#include "string_util.h"
#include "s3fs_logger.h"
#include "s3fs_util.h"
#include "autolock.h"
#include "curl.h"
#include "s3fs_cred.h"
@ -106,51 +105,23 @@ ino_t FdEntity::GetInode(int fd)
// FdEntity methods
//------------------------------------------------
FdEntity::FdEntity(const char* tpath, const char* cpath) :
is_lock_init(false), path(SAFESTRPTR(tpath)),
path(SAFESTRPTR(tpath)),
physical_fd(-1), pfile(nullptr), inode(0), size_orgmeta(0),
cachepath(SAFESTRPTR(cpath)), pending_status(pending_status_t::NO_UPDATE_PENDING)
{
holding_mtime.tv_sec = -1;
holding_mtime.tv_nsec = 0;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&fdent_lock, &attr))){
S3FS_PRN_CRIT("failed to init fdent_lock: %d", result);
abort();
}
if(0 != (result = pthread_mutex_init(&fdent_data_lock, &attr))){
S3FS_PRN_CRIT("failed to init fdent_data_lock: %d", result);
abort();
}
is_lock_init = true;
}
FdEntity::~FdEntity()
{
Clear();
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&fdent_data_lock))){
S3FS_PRN_CRIT("failed to destroy fdent_data_lock: %d", result);
abort();
}
if(0 != (result = pthread_mutex_destroy(&fdent_lock))){
S3FS_PRN_CRIT("failed to destroy fdent_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
void FdEntity::Clear()
{
AutoLock auto_lock(&fdent_lock);
AutoLock auto_data_lock(&fdent_data_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
pseudo_fd_map.clear();
@ -210,7 +181,7 @@ ino_t FdEntity::GetInode() const
void FdEntity::Close(int fd)
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d][physical_fd=%d]", path.c_str(), fd, physical_fd);
@ -224,7 +195,7 @@ void FdEntity::Close(int fd)
// check pseudo fd count
if(-1 != physical_fd && 0 == GetOpenCountHasLock()){
AutoLock auto_data_lock(&fdent_data_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
if(!cachepath.empty()){
// [NOTE]
// Compare the inode of the existing cache file with the inode of
@ -277,7 +248,7 @@ int FdEntity::DupWithLock(int fd)
int FdEntity::OpenPseudoFd(int flags)
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
S3FS_PRN_DBG("[path=%s][physical_fd=%d][pseudo fd count=%zu]", path.c_str(), physical_fd, pseudo_fd_map.size());
@ -411,8 +382,8 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts
{
S3FS_PRN_DBG("[path=%s][physical_fd=%d][size=%lld][ts_mctime=%s][flags=0x%x]", path.c_str(), physical_fd, static_cast<long long>(size), str(ts_mctime).c_str(), flags);
AutoLock lock(&fdent_lock);
AutoLock auto_data_lock(&fdent_data_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
// [NOTE]
// When the file size is incremental by truncating, it must be keeped
@ -676,7 +647,7 @@ int FdEntity::Open(const headers_t* pmeta, off_t size, const struct timespec& ts
//
bool FdEntity::LoadAll(int fd, headers_t* pmeta, off_t* size, bool force_load)
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
S3FS_PRN_INFO3("[path=%s][pseudo_fd=%d][physical_fd=%d]", path.c_str(), fd, physical_fd);
@ -685,7 +656,7 @@ bool FdEntity::LoadAll(int fd, headers_t* pmeta, off_t* size, bool force_load)
return false;
}
AutoLock auto_data_lock(&fdent_data_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
if(force_load){
SetAllStatusUnloaded();
@ -756,8 +727,8 @@ bool FdEntity::RenamePath(const std::string& newpath, std::string& fentmapkey)
bool FdEntity::IsModified() const
{
AutoLock auto_lock(&fdent_lock);
AutoLock auto_data_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
return pagelist.IsModified();
}
@ -839,7 +810,7 @@ int FdEntity::SetMCtimeHasLock(struct timespec mtime, struct timespec ctime)
bool FdEntity::UpdateCtime()
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
struct stat st;
if(!GetStatsHasLock(st)){
return false;
@ -852,7 +823,7 @@ bool FdEntity::UpdateCtime()
bool FdEntity::UpdateAtime()
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
struct stat st;
if(!GetStatsHasLock(st)){
return false;
@ -865,7 +836,7 @@ bool FdEntity::UpdateAtime()
bool FdEntity::UpdateMtime(bool clear_holding_mtime)
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
if(0 <= holding_mtime.tv_sec){
// [NOTE]
@ -903,7 +874,7 @@ bool FdEntity::SetHoldingMtime(struct timespec mtime)
{
S3FS_PRN_INFO3("[path=%s][physical_fd=%d][mtime=%s]", path.c_str(), physical_fd, str(mtime).c_str());
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
if(mtime.tv_sec < 0){
return false;
@ -960,19 +931,19 @@ bool FdEntity::ClearHoldingMtime()
bool FdEntity::GetSize(off_t& size) const
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
if(-1 == physical_fd){
return false;
}
AutoLock auto_data_lock(&fdent_data_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
size = pagelist.Size();
return true;
}
bool FdEntity::GetXattr(std::string& xattr) const
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
headers_t::const_iterator iter = orgmeta.find("x-amz-meta-xattr");
if(iter == orgmeta.end()){
@ -984,7 +955,7 @@ bool FdEntity::GetXattr(std::string& xattr) const
bool FdEntity::SetXattr(const std::string& xattr)
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
orgmeta["x-amz-meta-xattr"] = xattr;
return true;
}
@ -1012,7 +983,7 @@ bool FdEntity::SetContentType(const char* path)
if(!path){
return false;
}
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
orgmeta["Content-Type"] = S3fsCurl::LookupMimeType(path);
return true;
}
@ -1028,7 +999,7 @@ bool FdEntity::SetAllStatus(bool is_loaded)
// this method is only internal use, and calling after locking.
// so do not lock now.
//
//AutoLock auto_lock(&fdent_lock);
//const std::lock_guard<std::mutex> lock(fdent_lock);
// get file size
struct stat st{};
@ -1356,8 +1327,8 @@ int FdEntity::NoCacheCompleteMultipartPost(PseudoFdInfo* pseudo_obj)
off_t FdEntity::BytesModified()
{
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
return pagelist.BytesModified();
}
@ -1394,7 +1365,7 @@ int FdEntity::RowFlushHasLock(int fd, const char* tpath, bool force_sync)
}
PseudoFdInfo* pseudo_obj = miter->second.get();
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
int result;
if(!force_sync && !pagelist.IsModified() && !IsDirtyMetadata()){
@ -1971,14 +1942,14 @@ ssize_t FdEntity::Read(int fd, char* bytes, off_t start, size_t size, bool force
{
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), fd, physical_fd, static_cast<long long int>(start), size);
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
if(-1 == physical_fd || nullptr == CheckPseudoFdFlags(fd, false)){
S3FS_PRN_DBG("pseudo_fd(%d) to physical_fd(%d) for path(%s) is not opened or not readable", fd, physical_fd, path.c_str());
return -EBADF;
}
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
if(force_load){
pagelist.SetPageLoadedStatus(start, size, PageList::page_status::NOT_LOAD_MODIFIED);
@ -2035,7 +2006,7 @@ ssize_t FdEntity::Write(int fd, const char* bytes, off_t start, size_t size)
{
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), fd, physical_fd, static_cast<long long int>(start), size);
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
PseudoFdInfo* pseudo_obj = nullptr;
if(-1 == physical_fd || nullptr == (pseudo_obj = CheckPseudoFdFlags(fd, false))){
S3FS_PRN_ERR("pseudo_fd(%d) to physical_fd(%d) for path(%s) is not opened or not writable", fd, physical_fd, path.c_str());
@ -2046,7 +2017,7 @@ ssize_t FdEntity::Write(int fd, const char* bytes, off_t start, size_t size)
if(FdManager::IsCacheDir() && !FdManager::IsSafeDiskSpace(nullptr, size)){
FdManager::get()->CleanupCacheDir();
}
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
// check file size
if(pagelist.Size() < start){
@ -2376,7 +2347,7 @@ ssize_t FdEntity::WriteStreamUpload(PseudoFdInfo* pseudo_obj, const char* bytes,
//
bool FdEntity::MergeOrgMeta(headers_t& updatemeta)
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
merge_headers(orgmeta, updatemeta, true); // overwrite all keys
// [NOTE]
@ -2402,7 +2373,7 @@ bool FdEntity::MergeOrgMeta(headers_t& updatemeta)
SetAtimeHasLock(atime);
}
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
if(pending_status_t::NO_UPDATE_PENDING == pending_status && (IsUploading() || pagelist.IsModified())){
pending_status = pending_status_t::UPDATE_META_PENDING;
}
@ -2487,8 +2458,8 @@ bool FdEntity::PunchHole(off_t start, size_t size)
{
S3FS_PRN_DBG("[path=%s][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), physical_fd, static_cast<long long int>(start), size);
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
if(-1 == physical_fd){
return false;
@ -2530,8 +2501,8 @@ bool FdEntity::PunchHole(off_t start, size_t size)
//
void FdEntity::MarkDirtyNewFile()
{
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
pagelist.Init(0, false, true);
pending_status = pending_status_t::CREATE_FILE_PENDING;
@ -2539,7 +2510,7 @@ void FdEntity::MarkDirtyNewFile()
bool FdEntity::IsDirtyNewFile() const
{
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return (pending_status_t::CREATE_FILE_PENDING == pending_status);
}
@ -2551,8 +2522,8 @@ bool FdEntity::IsDirtyNewFile() const
//
void FdEntity::MarkDirtyMetadata()
{
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock2(&fdent_data_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
const std::lock_guard<std::mutex> data_lock(fdent_data_lock);
if(pending_status_t::NO_UPDATE_PENDING == pending_status){
pending_status = pending_status_t::UPDATE_META_PENDING;

View File

@ -24,8 +24,9 @@
#include <cstdint>
#include <fcntl.h>
#include <memory>
#include <mutex>
#include "autolock.h"
#include "common.h"
#include "fdcache_page.h"
#include "fdcache_fdinfo.h"
#include "fdcache_untreated.h"
@ -51,8 +52,7 @@ class FdEntity
static bool mixmultipart; // whether multipart uploading can use copy api.
static bool streamupload; // whether stream uploading.
mutable pthread_mutex_t fdent_lock;
bool is_lock_init;
mutable std::mutex fdent_lock;
std::string path; // object path
int physical_fd; // physical file(cache or temporary file) descriptor
UntreatedParts untreated_list; // list of untreated parts that have been written and not yet uploaded(for streamupload)
@ -62,7 +62,7 @@ class FdEntity
headers_t orgmeta; // original headers at opening
off_t size_orgmeta; // original file size in original headers
mutable pthread_mutex_t fdent_data_lock;// protects the following members
mutable std::mutex fdent_data_lock;// protects the following members
PageList pagelist;
std::string cachepath; // local cache file path
// (if this is empty, does not load/save pagelist.)
@ -117,20 +117,20 @@ class FdEntity
// TODO: should this require a lock?
bool IsOpen() const { return (-1 != physical_fd); }
bool FindPseudoFd(int fd) const {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return FindPseudoFdWithLock(fd);
}
bool FindPseudoFdWithLock(int fd) const REQUIRES(FdEntity::fdent_lock);
int Open(const headers_t* pmeta, off_t size, const struct timespec& ts_mctime, int flags) REQUIRES(FdEntity::fdent_lock);
bool LoadAll(int fd, headers_t* pmeta = nullptr, off_t* size = nullptr, bool force_load = false);
int Dup(int fd) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return DupWithLock(fd);
}
int DupWithLock(int fd) REQUIRES(FdEntity::fdent_lock);
int OpenPseudoFd(int flags = O_RDONLY);
int GetOpenCount() const {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return GetOpenCountHasLock();
}
int GetOpenCountHasLock() const REQUIRES(FdEntity::fdent_lock);
@ -141,28 +141,28 @@ class FdEntity
bool IsModified() const;
bool MergeOrgMeta(headers_t& updatemeta);
int UploadPending(int fd) {
AutoLock auto_lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return UploadPendingHasLock(fd);
}
int UploadPendingHasLock(int fd) REQUIRES(FdEntity::fdent_lock);
bool GetStats(struct stat& st) const {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return GetStatsHasLock(st);
}
bool GetStatsHasLock(struct stat& st) const REQUIRES(FdEntity::fdent_lock);
int SetCtime(struct timespec time) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return SetCtimeHasLock(time);
}
int SetCtimeHasLock(struct timespec time) REQUIRES(FdEntity::fdent_lock);
int SetAtime(struct timespec time) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return SetAtimeHasLock(time);
}
int SetAtimeHasLock(struct timespec time) REQUIRES(FdEntity::fdent_lock);
int SetMCtime(struct timespec mtime, struct timespec ctime) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return SetMCtimeHasLock(mtime, ctime);
}
int SetMCtimeHasLock(struct timespec mtime, struct timespec ctime) REQUIRES(FdEntity::fdent_lock);
@ -176,32 +176,32 @@ class FdEntity
bool GetXattr(std::string& xattr) const;
bool SetXattr(const std::string& xattr);
bool SetMode(mode_t mode) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return SetModeHasLock(mode);
}
bool SetModeHasLock(mode_t mode) REQUIRES(FdEntity::fdent_lock);
bool SetUId(uid_t uid) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return SetUIdHasLock(uid);
}
bool SetUIdHasLock(uid_t uid) REQUIRES(FdEntity::fdent_lock);
bool SetGId(gid_t gid) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return SetGIdHasLock(gid);
}
bool SetGIdHasLock(gid_t gid) REQUIRES(FdEntity::fdent_lock);
bool SetContentType(const char* path);
int Load(off_t start, off_t size, bool is_modified_flag = false) REQUIRES(FdEntity::fdent_lock, FdEntity::&fdent_data_lock); // size=0 means loading to end
int Load(off_t start, off_t size, bool is_modified_flag = false) REQUIRES(FdEntity::fdent_lock, FdEntity::fdent_data_lock); // size=0 means loading to end
off_t BytesModified();
int RowFlush(int fd, const char* tpath, bool force_sync = false) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return RowFlushHasLock(fd, tpath, force_sync);
}
int RowFlushHasLock(int fd, const char* tpath, bool force_sync = false) REQUIRES(FdEntity::fdent_lock);
int Flush(int fd, bool force_sync = false) {
AutoLock lock(&fdent_lock);
const std::lock_guard<std::mutex> lock(fdent_lock);
return FlushHasLock(fd, force_sync);
}
int FlushHasLock(int fd, bool force_sync = false) REQUIRES(FdEntity::fdent_lock) { return RowFlushHasLock(fd, nullptr, force_sync); }

View File

@ -58,7 +58,7 @@ void* PseudoFdInfo::MultipartUploadThreadWorker(void* arg)
int result;
{
AutoLock auto_lock(&(pthparam->ppseudofdinfo->upload_list_lock));
const std::lock_guard<std::mutex> lock(pthparam->ppseudofdinfo->upload_list_lock);
if(0 != (result = pthparam->ppseudofdinfo->last_result)){
S3FS_PRN_DBG("Already occurred error, thus this thread worker is exiting.");
@ -76,7 +76,7 @@ void* PseudoFdInfo::MultipartUploadThreadWorker(void* arg)
S3FS_PRN_ERR("failed creating s3fs curl object for uploading [path=%s][start=%lld][size=%lld][part=%d]", pthparam->path.c_str(), static_cast<long long>(pthparam->start), static_cast<long long>(pthparam->size), pthparam->part_num);
// set result for exiting
AutoLock auto_lock(&pthparam->ppseudofdinfo->upload_list_lock);
const std::lock_guard<std::mutex> lock(pthparam->ppseudofdinfo->upload_list_lock);
if(!pthparam->ppseudofdinfo->CompleteInstruction(result)){
result = -EIO;
}
@ -96,7 +96,7 @@ void* PseudoFdInfo::MultipartUploadThreadWorker(void* arg)
s3fscurl->DestroyCurlHandle(true, false);
// set result
AutoLock auto_lock(&pthparam->ppseudofdinfo->upload_list_lock);
const std::lock_guard<std::mutex> lock(pthparam->ppseudofdinfo->upload_list_lock);
if(!pthparam->ppseudofdinfo->CompleteInstruction(result)){
S3FS_PRN_WARN("This thread worker is about to end, so it doesn't return an EIO here and runs to the end.");
}
@ -109,18 +109,6 @@ void* PseudoFdInfo::MultipartUploadThreadWorker(void* arg)
//------------------------------------------------
PseudoFdInfo::PseudoFdInfo(int fd, int open_flags) : pseudo_fd(-1), physical_fd(fd), flags(0), upload_fd(-1), uploaded_sem(0), instruct_count(0), completed_count(0), last_result(0)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&upload_list_lock, &attr))){
S3FS_PRN_CRIT("failed to init upload_list_lock: %d", result);
abort();
}
is_lock_init = true;
if(-1 != physical_fd){
pseudo_fd = PseudoFdManager::Get();
flags = open_flags;
@ -130,15 +118,6 @@ PseudoFdInfo::PseudoFdInfo(int fd, int open_flags) : pseudo_fd(-1), physical_fd(
PseudoFdInfo::~PseudoFdInfo()
{
Clear(); // call before destroying the mutex
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&upload_list_lock))){
S3FS_PRN_CRIT("failed to destroy upload_list_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
bool PseudoFdInfo::Clear()
@ -149,7 +128,7 @@ bool PseudoFdInfo::Clear()
return false;
}
{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!ResetUploadInfo()){
@ -169,7 +148,7 @@ bool PseudoFdInfo::Clear()
void PseudoFdInfo::CloseUploadFd()
{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
if(-1 != upload_fd){
close(upload_fd);
@ -253,7 +232,7 @@ bool PseudoFdInfo::ClearUploadInfo(bool is_cancel_mp)
}
}
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
return ResetUploadInfo();
}
@ -277,7 +256,7 @@ bool PseudoFdInfo::RowInitialUploadInfo(const std::string& id, bool is_cancel_mp
return false;
}
}else{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
// cppcheck-suppress unmatchedSuppression
// cppcheck-suppress knownConditionTrueFalse
if(!ResetUploadInfo()){
@ -285,7 +264,7 @@ bool PseudoFdInfo::RowInitialUploadInfo(const std::string& id, bool is_cancel_mp
}
}
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
upload_id = id;
return true;
}
@ -323,7 +302,7 @@ bool PseudoFdInfo::GetEtaglist(etaglist_t& list) const
return false;
}
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
list.clear();
for(filepart_list_t::const_iterator iter = upload_list.begin(); iter != upload_list.end(); ++iter){
@ -351,7 +330,7 @@ bool PseudoFdInfo::AppendUploadPart(off_t start, off_t size, bool is_copy, etagp
return false;
}
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
off_t next_start_pos = 0;
if(!upload_list.empty()){
next_start_pos = upload_list.back().startpos + upload_list.back().size;
@ -470,7 +449,7 @@ bool PseudoFdInfo::ParallelMultipartUploadAll(const char* path, const mp_part_li
result = 0;
{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
if(!OpenUploadFd()){
return false;
}
@ -621,7 +600,7 @@ int PseudoFdInfo::WaitAllThreadsExit()
int result;
bool is_loop = true;
{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
if(0 == instruct_count && 0 == completed_count){
result = last_result;
is_loop = false;
@ -632,7 +611,7 @@ int PseudoFdInfo::WaitAllThreadsExit()
// need to wait the worker exiting
uploaded_sem.wait();
{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
if(0 < completed_count){
--completed_count;
}
@ -651,7 +630,7 @@ bool PseudoFdInfo::CancelAllThreads()
{
bool need_cancel = false;
{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
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;
@ -773,7 +752,7 @@ bool PseudoFdInfo::ExtractUploadPartsFromUntreatedArea(const off_t& untreated_st
//
bool PseudoFdInfo::ExtractUploadPartsFromAllArea(UntreatedParts& untreated_list, mp_part_list_t& to_upload_list, mp_part_list_t& to_copy_list, mp_part_list_t& to_download_list, filepart_list_t& cancel_upload_list, bool& wait_upload_complete, off_t max_mp_size, off_t file_size, bool use_copy)
{
AutoLock auto_lock(&upload_list_lock);
const std::lock_guard<std::mutex> lock(upload_list_lock);
// Initialize lists
to_upload_list.clear();

View File

@ -22,10 +22,11 @@
#define S3FS_FDCACHE_FDINFO_H_
#include <memory>
#include <mutex>
#include "common.h"
#include "psemaphore.h"
#include "metaheader.h"
#include "autolock.h"
#include "types.h"
class FdEntity;
@ -65,8 +66,7 @@ class PseudoFdInfo
int upload_fd; // duplicated fd for uploading
filepart_list_t upload_list;
petagpool etag_entities; // list of etag string and part number entities(to maintain the etag entity even if MPPART_INFO is destroyed)
bool is_lock_init;
mutable pthread_mutex_t upload_list_lock; // protects upload_id and upload_list
mutable std::mutex upload_list_lock; // protects upload_id and upload_list
Semaphore uploaded_sem; // use a semaphore to trigger an upload completion like event flag
int instruct_count; // number of instructions for processing by threads
int completed_count; // number of completed processes by thread
@ -77,12 +77,12 @@ class PseudoFdInfo
bool Clear();
void CloseUploadFd();
bool OpenUploadFd() REQUIRES(PseudoFdInfo::upload_list_lock);
bool ResetUploadInfo() REQUIRES(PseudoFdInfo::upload_list_lock);
bool OpenUploadFd() REQUIRES(upload_list_lock);
bool ResetUploadInfo() REQUIRES(upload_list_lock);
bool RowInitialUploadInfo(const std::string& id, bool is_cancel_mp);
bool CompleteInstruction(int result) REQUIRES(S3fsCurl::curl_handles_lock);
bool ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy) REQUIRES(PseudoFdInfo::upload_list_lock);
bool InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag) REQUIRES(PseudoFdInfo::upload_list_lock);
bool ParallelMultipartUpload(const char* path, const mp_part_list_t& mplist, bool is_copy) REQUIRES(upload_list_lock);
bool InsertUploadPart(off_t start, off_t size, int part_num, bool is_copy, etagpair** ppetag) REQUIRES(upload_list_lock);
bool CancelAllThreads();
bool ExtractUploadPartsFromUntreatedArea(const off_t& untreated_start, const off_t& untreated_size, mp_part_list_t& to_upload_list, filepart_list_t& cancel_upload_list, off_t max_mp_size);

View File

@ -24,7 +24,6 @@
#include "s3fs_logger.h"
#include "fdcache_pseudofd.h"
#include "autolock.h"
//------------------------------------------------
// Symbols
@ -57,33 +56,6 @@ bool PseudoFdManager::Release(int fd)
//------------------------------------------------
// PseudoFdManager methods
//------------------------------------------------
PseudoFdManager::PseudoFdManager() : is_lock_init(false)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&pseudofd_list_lock, &attr))){
S3FS_PRN_CRIT("failed to init pseudofd_list_lock: %d", result);
abort();
}
is_lock_init = true;
}
PseudoFdManager::~PseudoFdManager()
{
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&pseudofd_list_lock))){
S3FS_PRN_CRIT("failed to destroy pseudofd_list_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
int PseudoFdManager::GetUnusedMinPseudoFd() const
{
int min_fd = MIN_PSEUDOFD_NUMBER;
@ -101,7 +73,7 @@ int PseudoFdManager::GetUnusedMinPseudoFd() const
int PseudoFdManager::CreatePseudoFd()
{
AutoLock auto_lock(&pseudofd_list_lock);
const std::lock_guard<std::mutex> lock(pseudofd_list_lock);
int new_fd = PseudoFdManager::GetUnusedMinPseudoFd();
pseudofd_list.push_back(new_fd);
@ -112,7 +84,7 @@ int PseudoFdManager::CreatePseudoFd()
bool PseudoFdManager::ReleasePseudoFd(int fd)
{
AutoLock auto_lock(&pseudofd_list_lock);
const std::lock_guard<std::mutex> lock(pseudofd_list_lock);
for(pseudofd_list_t::iterator iter = pseudofd_list.begin(); iter != pseudofd_list.end(); ++iter){
if(fd == (*iter)){

View File

@ -21,7 +21,7 @@
#ifndef S3FS_FDCACHE_PSEUDOFD_H_
#define S3FS_FDCACHE_PSEUDOFD_H_
#include <pthread.h>
#include <mutex>
#include <vector>
//------------------------------------------------
@ -38,14 +38,13 @@ class PseudoFdManager
{
private:
pseudofd_list_t pseudofd_list;
bool is_lock_init;
pthread_mutex_t pseudofd_list_lock; // protects pseudofd_list
std::mutex pseudofd_list_lock; // protects pseudofd_list
private:
static PseudoFdManager& GetManager();
PseudoFdManager();
~PseudoFdManager();
PseudoFdManager() = default;
~PseudoFdManager() = default;
PseudoFdManager(const PseudoFdManager&) = delete;
PseudoFdManager(PseudoFdManager&&) = delete;
PseudoFdManager& operator=(const PseudoFdManager&) = delete;

View File

@ -22,42 +22,13 @@
#include "s3fs_logger.h"
#include "fdcache_untreated.h"
#include "autolock.h"
//------------------------------------------------
// UntreatedParts methods
//------------------------------------------------
UntreatedParts::UntreatedParts() : last_tag(0) //, is_lock_init(false)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&untreated_list_lock, &attr))){
S3FS_PRN_CRIT("failed to init untreated_list_lock: %d", result);
abort();
}
is_lock_init = true;
}
UntreatedParts::~UntreatedParts()
{
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&untreated_list_lock))){
S3FS_PRN_CRIT("failed to destroy untreated_list_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
bool UntreatedParts::empty()
{
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
return untreated_list.empty();
}
@ -67,7 +38,7 @@ bool UntreatedParts::AddPart(off_t start, off_t size)
S3FS_PRN_ERR("Parameter are wrong(start=%lld, size=%lld).", static_cast<long long int>(start), static_cast<long long int>(size));
return false;
}
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
++last_tag;
@ -105,7 +76,7 @@ bool UntreatedParts::RowGetPart(off_t& start, off_t& size, off_t max_size, off_t
S3FS_PRN_ERR("Parameter are wrong(max_size=%lld, min_size=%lld).", static_cast<long long int>(max_size), static_cast<long long int>(min_size));
return false;
}
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
// Check the overlap with the existing part and add the part.
for(untreated_list_t::const_iterator iter = untreated_list.begin(); iter != untreated_list.end(); ++iter){
@ -140,7 +111,7 @@ bool UntreatedParts::ClearParts(off_t start, off_t size)
S3FS_PRN_ERR("Parameter are wrong(start=%lld, size=%lld).", static_cast<long long int>(start), static_cast<long long int>(size));
return false;
}
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
if(untreated_list.empty()){
return true;
@ -193,7 +164,7 @@ bool UntreatedParts::ClearParts(off_t start, off_t size)
//
bool UntreatedParts::GetLastUpdatePart(off_t& start, off_t& size) const
{
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
for(untreated_list_t::const_iterator iter = untreated_list.begin(); iter != untreated_list.end(); ++iter){
if(iter->untreated_tag == last_tag){
@ -213,7 +184,7 @@ bool UntreatedParts::GetLastUpdatePart(off_t& start, off_t& size) const
//
bool UntreatedParts::ReplaceLastUpdatePart(off_t start, off_t size)
{
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
for(untreated_list_t::iterator iter = untreated_list.begin(); iter != untreated_list.end(); ++iter){
if(iter->untreated_tag == last_tag){
@ -234,7 +205,7 @@ bool UntreatedParts::ReplaceLastUpdatePart(off_t start, off_t size)
//
bool UntreatedParts::RemoveLastUpdatePart()
{
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
for(untreated_list_t::iterator iter = untreated_list.begin(); iter != untreated_list.end(); ++iter){
if(iter->untreated_tag == last_tag){
@ -250,7 +221,7 @@ bool UntreatedParts::RemoveLastUpdatePart()
//
bool UntreatedParts::Duplicate(untreated_list_t& list)
{
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
list = untreated_list;
return true;
@ -258,7 +229,7 @@ bool UntreatedParts::Duplicate(untreated_list_t& list)
void UntreatedParts::Dump()
{
AutoLock auto_lock(&untreated_list_lock);
const std::lock_guard<std::mutex> lock(untreated_list_lock);
S3FS_PRN_DBG("untreated list = [");
for(untreated_list_t::const_iterator iter = untreated_list.begin(); iter != untreated_list.end(); ++iter){

View File

@ -21,6 +21,8 @@
#ifndef S3FS_FDCACHE_UNTREATED_H_
#define S3FS_FDCACHE_UNTREATED_H_
#include <mutex>
#include "common.h"
#include "types.h"
@ -30,18 +32,17 @@
class UntreatedParts
{
private:
mutable pthread_mutex_t untreated_list_lock; // protects untreated_list
bool is_lock_init;
mutable std::mutex untreated_list_lock; // protects untreated_list
untreated_list_t untreated_list;
long last_tag; // [NOTE] Use this to identify the latest updated part.
long last_tag = 0; // [NOTE] Use this to identify the latest updated part.
private:
bool RowGetPart(off_t& start, off_t& size, off_t max_size, off_t min_size, bool lastpart) const;
public:
UntreatedParts();
~UntreatedParts();
UntreatedParts() = default;
~UntreatedParts() = default;
UntreatedParts(const UntreatedParts&) = delete;
UntreatedParts(UntreatedParts&&) = delete;
UntreatedParts& operator=(const UntreatedParts&) = delete;

View File

@ -25,6 +25,7 @@
#include <cstdio>
#include <cstdlib>
#include <cerrno>
#include <mutex>
#include <pthread.h>
#include <unistd.h>
#include <sys/stat.h>
@ -80,26 +81,19 @@ bool s3fs_destroy_global_ssl()
// internal use struct for openssl
struct CRYPTO_dynlock_value
{
pthread_mutex_t dyn_mutex;
std::mutex dyn_mutex;
};
static pthread_mutex_t* s3fs_crypt_mutex = nullptr;
static std::mutex* s3fs_crypt_mutex = nullptr;
static void s3fs_crypt_mutex_lock(int mode, int pos, const char* file, int line) __attribute__ ((unused));
static void s3fs_crypt_mutex_lock(int mode, int pos, const char* file, int line)
{
if(s3fs_crypt_mutex){
int result;
if(mode & CRYPTO_LOCK){
if(0 != (result = pthread_mutex_lock(&s3fs_crypt_mutex[pos]))){
S3FS_PRN_CRIT("pthread_mutex_lock returned: %d", result);
abort();
}
s3fs_crypt_mutex[pos].lock();
}else{
if(0 != (result = pthread_mutex_unlock(&s3fs_crypt_mutex[pos]))){
S3FS_PRN_CRIT("pthread_mutex_unlock returned: %d", result);
abort();
}
s3fs_crypt_mutex[pos].unlock();
}
}
}
@ -116,16 +110,6 @@ static struct CRYPTO_dynlock_value* s3fs_dyn_crypt_mutex(const char* file, int l
static struct CRYPTO_dynlock_value* s3fs_dyn_crypt_mutex(const char* file, int line)
{
struct CRYPTO_dynlock_value* dyndata = new CRYPTO_dynlock_value();
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&(dyndata->dyn_mutex), &attr))){
S3FS_PRN_CRIT("pthread_mutex_init returned: %d", result);
return nullptr;
}
return dyndata;
}
@ -133,17 +117,10 @@ static void s3fs_dyn_crypt_mutex_lock(int mode, struct CRYPTO_dynlock_value* dyn
static void s3fs_dyn_crypt_mutex_lock(int mode, struct CRYPTO_dynlock_value* dyndata, const char* file, int line)
{
if(dyndata){
int result;
if(mode & CRYPTO_LOCK){
if(0 != (result = pthread_mutex_lock(&(dyndata->dyn_mutex)))){
S3FS_PRN_CRIT("pthread_mutex_lock returned: %d", result);
abort();
}
dyndata->dyn_mutex.lock();
}else{
if(0 != (result = pthread_mutex_unlock(&(dyndata->dyn_mutex)))){
S3FS_PRN_CRIT("pthread_mutex_unlock returned: %d", result);
abort();
}
dyndata->dyn_mutex.unlock();
}
}
}
@ -151,14 +128,7 @@ static void s3fs_dyn_crypt_mutex_lock(int mode, struct CRYPTO_dynlock_value* dyn
static void s3fs_destroy_dyn_crypt_mutex(struct CRYPTO_dynlock_value* dyndata, const char* file, int line) __attribute__ ((unused));
static void s3fs_destroy_dyn_crypt_mutex(struct CRYPTO_dynlock_value* dyndata, const char* file, int line)
{
if(dyndata){
int result = pthread_mutex_destroy(&(dyndata->dyn_mutex));
if(result != 0){
S3FS_PRN_CRIT("failed to destroy dyn_mutex");
abort();
}
delete dyndata;
}
delete dyndata;
}
bool s3fs_init_crypt_mutex()
@ -173,19 +143,7 @@ bool s3fs_init_crypt_mutex()
return false;
}
}
s3fs_crypt_mutex = new pthread_mutex_t[CRYPTO_num_locks()];
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
for(int cnt = 0; cnt < CRYPTO_num_locks(); cnt++){
int result = pthread_mutex_init(&s3fs_crypt_mutex[cnt], &attr);
if(result != 0){
S3FS_PRN_CRIT("pthread_mutex_init returned: %d", result);
return false;
}
}
s3fs_crypt_mutex = new std::mutex[CRYPTO_num_locks()];
// static lock
CRYPTO_set_locking_callback(s3fs_crypt_mutex_lock);
CRYPTO_set_id_callback(s3fs_crypt_get_threadid);
@ -209,13 +167,6 @@ bool s3fs_destroy_crypt_mutex()
CRYPTO_set_id_callback(nullptr);
CRYPTO_set_locking_callback(nullptr);
for(int cnt = 0; cnt < CRYPTO_num_locks(); cnt++){
int result = pthread_mutex_destroy(&s3fs_crypt_mutex[cnt]);
if(result != 0){
S3FS_PRN_CRIT("failed to destroy s3fs_crypt_mutex[%d]", cnt);
abort();
}
}
CRYPTO_cleanup_all_ex_data();
delete[] s3fs_crypt_mutex;
s3fs_crypt_mutex = nullptr;

View File

@ -24,6 +24,7 @@
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <mutex>
#include <set>
#include <unistd.h>
#include <dirent.h>
@ -51,7 +52,6 @@
#include "s3fs_util.h"
#include "mpu_util.h"
#include "threadpoolman.h"
#include "autolock.h"
//-------------------------------------------------------------------
// Symbols
@ -239,17 +239,16 @@ static MpStatFlag* pHasMpStat = nullptr;
class SyncFiller
{
private:
mutable pthread_mutex_t filler_lock;
bool is_lock_init = false;
mutable std::mutex filler_lock;
void* filler_buff;
fuse_fill_dir_t filler_func;
std::set<std::string> filled;
public:
explicit SyncFiller(void* buff = nullptr, fuse_fill_dir_t filler = nullptr);
~SyncFiller() = default;
SyncFiller(const SyncFiller&) = delete;
SyncFiller(SyncFiller&&) = delete;
~SyncFiller();
SyncFiller& operator=(const SyncFiller&) = delete;
SyncFiller& operator=(SyncFiller&&) = delete;
@ -263,31 +262,6 @@ SyncFiller::SyncFiller(void* buff, fuse_fill_dir_t filler) : filler_buff(buff),
S3FS_PRN_CRIT("Internal error: SyncFiller constructor parameter is critical value.");
abort();
}
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&filler_lock, &attr))){
S3FS_PRN_CRIT("failed to init filler_lock: %d", result);
abort();
}
is_lock_init = true;
}
SyncFiller::~SyncFiller()
{
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&filler_lock))){
S3FS_PRN_CRIT("failed to destroy filler_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
//
@ -295,7 +269,7 @@ SyncFiller::~SyncFiller()
//
int SyncFiller::Fill(const char *name, const struct stat *stbuf, off_t off)
{
AutoLock auto_lock(&filler_lock);
const std::lock_guard<std::mutex> lock(filler_lock);
int result = 0;
if(filled.insert(name).second){
@ -306,7 +280,7 @@ int SyncFiller::Fill(const char *name, const struct stat *stbuf, off_t off)
int SyncFiller::SufficiencyFill(const std::vector<std::string>& pathlist)
{
AutoLock auto_lock(&filler_lock);
const std::lock_guard<std::mutex> lock(filler_lock);
int result = 0;
for(std::vector<std::string>::const_iterator it = pathlist.begin(); it != pathlist.end(); ++it) {
@ -3213,7 +3187,7 @@ static bool multi_head_callback(S3fsCurl* s3fscurl, void* param)
struct multi_head_notfound_callback_param
{
pthread_mutex_t list_lock;
std::mutex list_lock;
s3obj_list_t notfound_list;
};
@ -3232,7 +3206,7 @@ static bool multi_head_notfound_callback(S3fsCurl* s3fscurl, void* param)
// set path to not found list
struct multi_head_notfound_callback_param* pcbparam = reinterpret_cast<struct multi_head_notfound_callback_param*>(param);
AutoLock auto_lock(&(pcbparam->list_lock));
const std::lock_guard<std::mutex> lock(pcbparam->list_lock);
pcbparam->notfound_list.push_back(s3fscurl->GetBasePath());
return true;
@ -3295,16 +3269,6 @@ static int readdir_multi_head(const char* path, const S3ObjList& head, void* buf
// Not found Callback function parameter
struct multi_head_notfound_callback_param notfound_param;
if(support_compat_dir){
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
if(0 != (result = pthread_mutex_init(&(notfound_param.list_lock), &attr))){
S3FS_PRN_CRIT("failed to init notfound_param.list_lock: %d", result);
abort();
}
curlmulti.SetNotFoundCallback(multi_head_notfound_callback);
curlmulti.SetNotFoundCallbackParam(reinterpret_cast<void*>(&notfound_param));
}

View File

@ -169,7 +169,6 @@ bool S3fsCred::ParseIAMRoleFromMetaDataResponse(const char* response, std::strin
// Methods : Constructor / Destructor
//-------------------------------------------------------------------
S3fsCred::S3fsCred() :
is_lock_init(false),
aws_profile(DEFAULT_AWS_PROFILE_NAME),
load_iamrole(false),
AWSAccessTokenExpire(0),
@ -188,31 +187,11 @@ S3fsCred::S3fsCred() :
pFuncCredFree(FreeS3fsCredential),
pFuncCredUpdate(UpdateS3fsCredential)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&token_lock, &attr))){
S3FS_PRN_CRIT("failed to init token_lock: %d", result);
abort();
}
is_lock_init = true;
}
S3fsCred::~S3fsCred()
{
UnloadExtCredLib();
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&token_lock))){
S3FS_PRN_CRIT("failed to destroy token_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
//-------------------------------------------------------------------
@ -486,7 +465,7 @@ bool S3fsCred::LoadIAMCredentials()
//
bool S3fsCred::LoadIAMRoleFromMetaData()
{
AutoLock auto_lock(&token_lock);
const std::lock_guard<std::mutex> lock(token_lock);
if(load_iamrole){
// url(not check iam role)
@ -1116,7 +1095,7 @@ bool S3fsCred::ParseIAMCredentialResponse(const char* response, iamcredmap_t& ke
bool S3fsCred::CheckIAMCredentialUpdate(std::string* access_key_id, std::string* secret_access_key, std::string* access_token)
{
AutoLock auto_lock(&token_lock);
const std::lock_guard<std::mutex> lock(token_lock);
if(IsIBMIAMAuth() || IsSetExtCredLib() || is_ecs || IsSetIAMRole()){
if(AWSAccessTokenExpire < (time(nullptr) + S3fsCred::IAM_EXPIRE_MERGING)){
@ -1374,7 +1353,7 @@ bool S3fsCred::UpdateExtCredentials()
//
int S3fsCred::DetectParam(const char* arg)
{
AutoLock auto_lock(&token_lock);
const std::lock_guard<std::mutex> lock(token_lock);
if(!arg){
S3FS_PRN_EXIT("parameter arg is empty(null)");
@ -1524,7 +1503,7 @@ bool S3fsCred::CheckForbiddenBucketParams()
//
bool S3fsCred::CheckAllParams()
{
AutoLock auto_lock(&token_lock);
const std::lock_guard<std::mutex> lock(token_lock);
//
// Checking forbidden parameters for bucket
//

View File

@ -22,9 +22,10 @@
#define S3FS_CRED_H_
#include <map>
#include <mutex>
#include <string>
#include "autolock.h"
#include "common.h"
#include "s3fs_extcred.h"
#include "types.h"
@ -57,8 +58,7 @@ class S3fsCred
static std::string bucket_name;
mutable pthread_mutex_t token_lock;
bool is_lock_init;
mutable std::mutex token_lock;
std::string passwd_file;
std::string aws_profile;

View File

@ -24,6 +24,7 @@
#include <cerrno>
#include <grp.h>
#include <memory>
#include <mutex>
#include <pwd.h>
#include <libgen.h>
#include <dirent.h>
@ -37,7 +38,6 @@
#include "s3fs_util.h"
#include "string_util.h"
#include "s3fs_help.h"
#include "autolock.h"
//-------------------------------------------------------------------
// Global variables
@ -167,52 +167,21 @@ int is_uid_include_group(uid_t uid, gid_t gid)
// conflicts.
// To avoid this, exclusive control is performed by mutex.
//
static pthread_mutex_t* pbasename_lock = nullptr;
static std::mutex basename_lock;
bool init_basename_lock()
{
if(pbasename_lock){
S3FS_PRN_ERR("already initialized mutex for posix dirname/basename function.");
return false;
}
pbasename_lock = new pthread_mutex_t;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(pbasename_lock, &attr))){
S3FS_PRN_ERR("failed to init pbasename_lock: %d.", result);
delete pbasename_lock;
pbasename_lock = nullptr;
return false;
}
return true;
}
bool destroy_basename_lock()
{
if(!pbasename_lock){
S3FS_PRN_ERR("the mutex for posix dirname/basename function is not initialized.");
return false;
}
int result;
if(0 != (result = pthread_mutex_destroy(pbasename_lock))){
S3FS_PRN_ERR("failed to destroy pbasename_lock: %d", result);
return false;
}
delete pbasename_lock;
pbasename_lock = nullptr;
return true;
}
std::string mydirname(const std::string& path)
{
AutoLock auto_lock(pbasename_lock);
const std::lock_guard<std::mutex> lock(basename_lock);
return mydirname(path.c_str());
}
@ -233,7 +202,7 @@ std::string mydirname(const char* path)
std::string mybasename(const std::string& path)
{
AutoLock auto_lock(pbasename_lock);
const std::lock_guard<std::mutex> data_lock(basename_lock);
return mybasename(path.c_str());
}

View File

@ -21,6 +21,7 @@
#include <cstdio>
#include <cstdlib>
#include <libxml/xpathInternals.h>
#include <mutex>
#include "common.h"
#include "s3fs.h"
@ -28,7 +29,6 @@
#include "s3fs_xml.h"
#include "s3fs_util.h"
#include "s3objlist.h"
#include "autolock.h"
#include "string_util.h"
//-------------------------------------------------------------------
@ -39,7 +39,7 @@ static constexpr char c_strErrorObjectName[] = "FILE or SUBDIR in DIR";
// [NOTE]
// mutex for static variables in GetXmlNsUrl
//
static pthread_mutex_t* pxml_parser_mutex = nullptr;
static std::mutex xml_parser_mutex;
//-------------------------------------------------------------------
// Functions
@ -48,7 +48,7 @@ static bool GetXmlNsUrl(xmlDocPtr doc, std::string& nsurl)
{
bool result = false;
if(!pxml_parser_mutex || !doc){
if(!doc){
return result;
}
@ -57,7 +57,7 @@ static bool GetXmlNsUrl(xmlDocPtr doc, std::string& nsurl)
static time_t tmLast = 0; // cache for 60 sec.
static std::string strNs;
AutoLock lock(pxml_parser_mutex);
const std::lock_guard<std::mutex> lock(xml_parser_mutex);
if((tmLast + 60) < time(nullptr)){
// refresh
@ -487,36 +487,11 @@ bool simple_parse_xml(const char* data, size_t len, const char* key, std::string
//-------------------------------------------------------------------
bool init_parser_xml_lock()
{
if(pxml_parser_mutex){
return false;
}
pxml_parser_mutex = new pthread_mutex_t;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
if(0 != pthread_mutex_init(pxml_parser_mutex, &attr)){
delete pxml_parser_mutex;
pxml_parser_mutex = nullptr;
return false;
}
return true;
}
bool destroy_parser_xml_lock()
{
if(!pxml_parser_mutex){
return false;
}
if(0 != pthread_mutex_destroy(pxml_parser_mutex)){
return false;
}
delete pxml_parser_mutex;
pxml_parser_mutex = nullptr;
return true;
}

View File

@ -25,7 +25,6 @@
#include "s3fs_logger.h"
#include "threadpoolman.h"
#include "autolock.h"
//------------------------------------------------
// ThreadPoolMan class variables
@ -87,7 +86,7 @@ void* ThreadPoolMan::Worker(void* arg)
// get instruction
thpoolman_param param;
{
AutoLock auto_lock(&(psingleton->thread_list_lock));
const std::lock_guard<std::mutex> lock(psingleton->thread_list_lock);
if(psingleton->instruction_list.empty()){
S3FS_PRN_DBG("Got a semaphore, but the instruction is empty.");
@ -113,7 +112,7 @@ void* ThreadPoolMan::Worker(void* arg)
//------------------------------------------------
// ThreadPoolMan methods
//------------------------------------------------
ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0), is_lock_init(false)
ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0)
{
if(count < 1){
S3FS_PRN_CRIT("Failed to creating singleton for Thread Manager, because thread count(%d) is under 1.", count);
@ -124,19 +123,6 @@ ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0), is_l
abort();
}
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&thread_list_lock, &attr))){
S3FS_PRN_CRIT("failed to init thread_list_lock: %d", result);
abort();
}
is_lock_init = true;
// create threads
if(!StartThreads(count)){
S3FS_PRN_ERR("Failed starting threads at initializing.");
@ -147,15 +133,6 @@ ThreadPoolMan::ThreadPoolMan(int count) : is_exit(false), thpoolman_sem(0), is_l
ThreadPoolMan::~ThreadPoolMan()
{
StopThreads();
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&thread_list_lock))){
S3FS_PRN_CRIT("failed to destroy thread_list_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
bool ThreadPoolMan::IsExit() const
@ -235,7 +212,7 @@ void ThreadPoolMan::SetInstruction(const thpoolman_param& param)
{
// set parameter to list
{
AutoLock auto_lock(&thread_list_lock);
const std::lock_guard<std::mutex> lock(thread_list_lock);
instruction_list.push_back(param);
}

View File

@ -23,7 +23,7 @@
#include <atomic>
#include <list>
#include <pthread.h>
#include <mutex>
#include <vector>
#include "psemaphore.h"
@ -66,8 +66,7 @@ class ThreadPoolMan
std::atomic<bool> is_exit;
Semaphore thpoolman_sem;
bool is_lock_init;
pthread_mutex_t thread_list_lock;
std::mutex thread_list_lock;
thread_list_t thread_list;
thpoolman_params_t instruction_list;