File locking refactored (#631)
Remove FileMutex and wire locking into driver subsystems.
This commit is contained in:
committed by
GitHub
parent
92ca046681
commit
020aa471e2
@@ -1,12 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
// Minimal filesystem helpers shared by app-module internals that need to look at on-disk app
|
||||
// directories (app_install.cpp, manager.cpp's install-path scan) - app-module may not depend
|
||||
// upward on Tactility::file, so this is a small local re-implementation (see
|
||||
// app_metadata_parsing.cpp for the same constraint applied to properties-file loading).
|
||||
|
||||
#include <tactility/filesystem/file_mutex.h>
|
||||
// Minimal filesystem helpers shared by app-module internals.
|
||||
|
||||
#include <cstring>
|
||||
#include <dirent.h>
|
||||
@@ -21,22 +16,12 @@
|
||||
|
||||
inline bool app_fs_is_directory(const std::string& path) {
|
||||
struct stat result {};
|
||||
FileMutex file_mutex;
|
||||
file_mutex_get(&file_mutex, path.c_str());
|
||||
file_mutex_lock(&file_mutex);
|
||||
auto is_dir = stat(path.c_str(), &result) == 0 && S_ISDIR(result.st_mode);
|
||||
file_mutex_unlock(&file_mutex);
|
||||
return is_dir;
|
||||
return stat(path.c_str(), &result) == 0 && S_ISDIR(result.st_mode);
|
||||
}
|
||||
|
||||
inline bool app_fs_is_file(const std::string& path) {
|
||||
FileMutex file_mutex;
|
||||
file_mutex_get(&file_mutex, path.c_str());
|
||||
file_mutex_lock(&file_mutex);
|
||||
struct stat result {};
|
||||
auto retval = stat(path.c_str(), &result) == 0 && S_ISREG(result.st_mode);
|
||||
file_mutex_unlock(&file_mutex);
|
||||
return retval;
|
||||
return stat(path.c_str(), &result) == 0 && S_ISREG(result.st_mode);
|
||||
}
|
||||
|
||||
// Appends the full path of every direct subdirectory of @a path to @a out.
|
||||
@@ -53,15 +38,11 @@ inline bool app_fs_delete_recursively(const std::string& path) {
|
||||
// ESP-IDF newlib has no lstat(); ESP32 filesystems (FAT/SPIFFS) don't
|
||||
// support symlinks, so stat() is equivalent there.
|
||||
struct stat st {};
|
||||
FileMutex file_mutex;
|
||||
file_mutex_get(&file_mutex, path.c_str());
|
||||
file_mutex_lock(&file_mutex);
|
||||
#ifdef ESP_PLATFORM
|
||||
int rc = stat(path.c_str(), &st);
|
||||
#else
|
||||
int rc = lstat(path.c_str(), &st);
|
||||
#endif
|
||||
file_mutex_unlock(&file_mutex);
|
||||
|
||||
if (rc != 0) {
|
||||
return false;
|
||||
@@ -70,24 +51,15 @@ inline bool app_fs_delete_recursively(const std::string& path) {
|
||||
#ifndef ESP_PLATFORM
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
// Symlink — remove as a leaf regardless of its target.
|
||||
file_mutex_lock(&file_mutex);
|
||||
bool result = unlink(path.c_str()) == 0;
|
||||
file_mutex_unlock(&file_mutex);
|
||||
return result;
|
||||
return unlink(path.c_str()) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
// Collect child names while locked, then release before recursing —
|
||||
// child paths can resolve to the same mount mutex (see
|
||||
// app_fs_list_direct_subdirectories comment), so holding the parent
|
||||
// lock across the recursive call would self-deadlock.
|
||||
std::vector<std::string> children;
|
||||
|
||||
file_mutex_lock(&file_mutex);
|
||||
DIR* dir = opendir(path.c_str());
|
||||
if (dir == nullptr) {
|
||||
file_mutex_unlock(&file_mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -99,7 +71,6 @@ inline bool app_fs_delete_recursively(const std::string& path) {
|
||||
children.push_back(path + "/" + entry->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
file_mutex_unlock(&file_mutex);
|
||||
|
||||
bool success = true;
|
||||
for (const auto& child : children) {
|
||||
@@ -109,33 +80,18 @@ inline bool app_fs_delete_recursively(const std::string& path) {
|
||||
}
|
||||
}
|
||||
|
||||
file_mutex_lock(&file_mutex);
|
||||
bool result = rmdir(path.c_str()) == 0;
|
||||
file_mutex_unlock(&file_mutex);
|
||||
return result;
|
||||
return rmdir(path.c_str()) == 0;
|
||||
}
|
||||
|
||||
// Regular file or other — unlink.
|
||||
file_mutex_lock(&file_mutex);
|
||||
bool result = unlink(path.c_str()) == 0;
|
||||
file_mutex_unlock(&file_mutex);
|
||||
return result;
|
||||
return unlink(path.c_str()) == 0;
|
||||
}
|
||||
|
||||
inline void app_fs_list_direct_subdirectories(const std::string& path, std::vector<std::string>& out) {
|
||||
// Collect child names while the directory lock is held, then release it before classifying
|
||||
// each one with app_fs_is_directory() - that function looks up and locks a FileMutex too,
|
||||
// and file_mutex_get() resolves a child path to the same registered mutex as its parent
|
||||
// mount. Calling it while still holding the directory's own lock would be a nested
|
||||
// acquisition of that same (possibly non-recursive) mutex, and could self-deadlock.
|
||||
std::vector<std::string> children;
|
||||
|
||||
FileMutex file_mutex;
|
||||
file_mutex_get(&file_mutex, path.c_str());
|
||||
file_mutex_lock(&file_mutex);
|
||||
DIR* dir = opendir(path.c_str());
|
||||
if (dir == nullptr) {
|
||||
file_mutex_unlock(&file_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -148,7 +104,6 @@ inline void app_fs_list_direct_subdirectories(const std::string& path, std::vect
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
file_mutex_unlock(&file_mutex);
|
||||
|
||||
for (const auto& child_path : children) {
|
||||
if (app_fs_is_directory(child_path)) {
|
||||
|
||||
Reference in New Issue
Block a user