Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of FATFileSystem by
Revision 8:c4baca9a2c3d, committed 2016-08-25
- Comitter:
- Kojto
- Date:
- Thu Aug 25 09:34:29 2016 +0100
- Parent:
- 7:094f84646b9f
- Commit message:
- Synchronized with git revision 4047ff95767d307
- fix _name error (getName())
- add thread safety
Changed in this revision
--- a/FATDirHandle.cpp Fri Dec 11 16:16:25 2015 +0000 +++ b/FATDirHandle.cpp Thu Aug 25 09:34:29 2016 +0100 @@ -25,12 +25,14 @@ using namespace mbed; -FATDirHandle::FATDirHandle(const FATFS_DIR &the_dir) { +FATDirHandle::FATDirHandle(const FATFS_DIR &the_dir, PlatformMutex * mutex): _mutex(mutex) { dir = the_dir; } int FATDirHandle::closedir() { + lock(); int retval = f_closedir(&dir); + unlock(); delete this; return retval; } @@ -38,6 +40,7 @@ struct dirent *FATDirHandle::readdir() { FILINFO finfo; + lock(); #if _USE_LFN finfo.lfname = cur_entry.d_name; finfo.lfsize = sizeof(cur_entry.d_name); @@ -47,33 +50,52 @@ #if _USE_LFN if(res != 0 || finfo.fname[0]==0) { + unlock(); return NULL; } else { if(cur_entry.d_name[0]==0) { // No long filename so use short filename. memcpy(cur_entry.d_name, finfo.fname, sizeof(finfo.fname)); } + unlock(); return &cur_entry; } #else if(res != 0 || finfo.fname[0]==0) { + unlock(); return NULL; } else { memcpy(cur_entry.d_name, finfo.fname, sizeof(finfo.fname)); + unlock(); return &cur_entry; } #endif /* _USE_LFN */ } void FATDirHandle::rewinddir() { + lock(); dir.index = 0; + unlock(); } off_t FATDirHandle::telldir() { - return dir.index; + lock(); + off_t offset = dir.index; + unlock(); + return offset; } void FATDirHandle::seekdir(off_t location) { + lock(); dir.index = location; + unlock(); } +void FATDirHandle::lock() { + _mutex->lock(); +} + +void FATDirHandle::unlock() { + _mutex->unlock(); +} +
--- a/FATDirHandle.h Fri Dec 11 16:16:25 2015 +0000 +++ b/FATDirHandle.h Thu Aug 25 09:34:29 2016 +0100 @@ -23,19 +23,27 @@ #define MBED_FATDIRHANDLE_H #include "DirHandle.h" +#include "PlatformMutex.h" using namespace mbed; class FATDirHandle : public DirHandle { public: - FATDirHandle(const FATFS_DIR &the_dir); + FATDirHandle(const FATFS_DIR &the_dir, PlatformMutex * mutex); virtual int closedir(); virtual struct dirent *readdir(); virtual void rewinddir(); virtual off_t telldir(); virtual void seekdir(off_t location); + protected: + + virtual void lock(); + virtual void unlock(); + + PlatformMutex * _mutex; + private: FATFS_DIR dir; struct dirent cur_entry;
--- a/FATFileHandle.cpp Fri Dec 11 16:16:25 2015 +0000 +++ b/FATFileHandle.cpp Thu Aug 25 09:34:29 2016 +0100 @@ -25,34 +25,42 @@ #include "FATFileHandle.h" -FATFileHandle::FATFileHandle(FIL fh) { +FATFileHandle::FATFileHandle(FIL fh, PlatformMutex * mutex): _mutex(mutex) { _fh = fh; } int FATFileHandle::close() { + lock(); int retval = f_close(&_fh); + unlock(); delete this; return retval; } ssize_t FATFileHandle::write(const void* buffer, size_t length) { + lock(); UINT n; FRESULT res = f_write(&_fh, buffer, length, &n); if (res) { debug_if(FFS_DBG, "f_write() failed: %d", res); + unlock(); return -1; } + unlock(); return n; } ssize_t FATFileHandle::read(void* buffer, size_t length) { + lock(); debug_if(FFS_DBG, "read(%d)\n", length); UINT n; FRESULT res = f_read(&_fh, buffer, length, &n); if (res) { debug_if(FFS_DBG, "f_read() failed: %d\n", res); + unlock(); return -1; } + unlock(); return n; } @@ -61,6 +69,7 @@ } off_t FATFileHandle::lseek(off_t position, int whence) { + lock(); if (whence == SEEK_END) { position += _fh.fsize; } else if(whence==SEEK_CUR) { @@ -69,22 +78,38 @@ FRESULT res = f_lseek(&_fh, position); if (res) { debug_if(FFS_DBG, "lseek failed: %d\n", res); + unlock(); return -1; } else { debug_if(FFS_DBG, "lseek OK, returning %i\n", _fh.fptr); + unlock(); return _fh.fptr; } } int FATFileHandle::fsync() { + lock(); FRESULT res = f_sync(&_fh); if (res) { debug_if(FFS_DBG, "f_sync() failed: %d\n", res); + unlock(); return -1; } + unlock(); return 0; } off_t FATFileHandle::flen() { - return _fh.fsize; + lock(); + off_t size = _fh.fsize; + unlock(); + return size; } + +void FATFileHandle::lock() { + _mutex->lock(); +} + +void FATFileHandle::unlock() { + _mutex->unlock(); +}
--- a/FATFileHandle.h Fri Dec 11 16:16:25 2015 +0000 +++ b/FATFileHandle.h Thu Aug 25 09:34:29 2016 +0100 @@ -23,13 +23,14 @@ #define MBED_FATFILEHANDLE_H #include "FileHandle.h" +#include "PlatformMutex.h" using namespace mbed; class FATFileHandle : public FileHandle { public: - FATFileHandle(FIL fh); + FATFileHandle(FIL fh, PlatformMutex * mutex); virtual int close(); virtual ssize_t write(const void* buffer, size_t length); virtual ssize_t read(void* buffer, size_t length); @@ -40,7 +41,11 @@ protected: + virtual void lock(); + virtual void unlock(); + FIL _fh; + PlatformMutex * _mutex; };
--- a/FATFileSystem.cpp Fri Dec 11 16:16:25 2015 +0000 +++ b/FATFileSystem.cpp Thu Aug 25 09:34:29 2016 +0100 @@ -27,6 +27,7 @@ #include "FATFileSystem.h" #include "FATFileHandle.h" #include "FATDirHandle.h" +#include "critical.h" DWORD get_fattime(void) { time_t rawtime; @@ -41,33 +42,55 @@ } FATFileSystem *FATFileSystem::_ffs[_VOLUMES] = {0}; +static PlatformMutex * mutex = NULL; -FATFileSystem::FATFileSystem(const char* n) : FileSystemLike(n) { +PlatformMutex * get_fat_mutex() { + PlatformMutex * new_mutex = new PlatformMutex; + + core_util_critical_section_enter(); + if (NULL == mutex) { + mutex = new_mutex; + } + core_util_critical_section_exit(); + + if (mutex != new_mutex) { + delete new_mutex; + } + return mutex; +} + +FATFileSystem::FATFileSystem(const char* n) : FileSystemLike(n), _mutex(get_fat_mutex()) { + lock(); debug_if(FFS_DBG, "FATFileSystem(%s)\n", n); for(int i=0; i<_VOLUMES; i++) { if(_ffs[i] == 0) { _ffs[i] = this; _fsid[0] = '0' + i; _fsid[1] = '\0'; - debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%s]\n", _name, _fsid); + debug_if(FFS_DBG, "Mounting [%s] on ffs drive [%s]\n", getName(), _fsid); f_mount(&_fs, _fsid, 0); + unlock(); return; } } error("Couldn't create %s in FATFileSystem::FATFileSystem\n", n); + unlock(); } FATFileSystem::~FATFileSystem() { + lock(); for (int i=0; i<_VOLUMES; i++) { if (_ffs[i] == this) { _ffs[i] = 0; f_mount(NULL, _fsid, 0); } } + unlock(); } FileHandle *FATFileSystem::open(const char* name, int flags) { - debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%s]\n", name, _name, _fsid); + lock(); + debug_if(FFS_DBG, "open(%s) on filesystem [%s], drv [%s]\n", name, getName(), _fsid); char n[64]; sprintf(n, "%s:/%s", _fsid, name); @@ -92,63 +115,95 @@ FRESULT res = f_open(&fh, n, openmode); if (res) { debug_if(FFS_DBG, "f_open('w') failed: %d\n", res); + unlock(); return NULL; } if (flags & O_APPEND) { f_lseek(&fh, fh.fsize); } - return new FATFileHandle(fh); + FATFileHandle * handle = new FATFileHandle(fh, _mutex); + unlock(); + return handle; } int FATFileSystem::remove(const char *filename) { + lock(); FRESULT res = f_unlink(filename); if (res) { debug_if(FFS_DBG, "f_unlink() failed: %d\n", res); + unlock(); return -1; } + unlock(); return 0; } int FATFileSystem::rename(const char *oldname, const char *newname) { + lock(); FRESULT res = f_rename(oldname, newname); if (res) { debug_if(FFS_DBG, "f_rename() failed: %d\n", res); + unlock(); return -1; } + unlock(); return 0; } int FATFileSystem::format() { + lock(); FRESULT res = f_mkfs(_fsid, 0, 512); // Logical drive number, Partitioning rule, Allocation unit size (bytes per cluster) if (res) { debug_if(FFS_DBG, "f_mkfs() failed: %d\n", res); + unlock(); return -1; } + unlock(); return 0; } DirHandle *FATFileSystem::opendir(const char *name) { + lock(); FATFS_DIR dir; FRESULT res = f_opendir(&dir, name); if (res != 0) { + unlock(); return NULL; } - return new FATDirHandle(dir); + FATDirHandle *handle = new FATDirHandle(dir, _mutex); + unlock(); + return handle; } int FATFileSystem::mkdir(const char *name, mode_t mode) { + lock(); FRESULT res = f_mkdir(name); + unlock(); return res == 0 ? 0 : -1; } int FATFileSystem::mount() { + lock(); FRESULT res = f_mount(&_fs, _fsid, 1); + unlock(); return res == 0 ? 0 : -1; } int FATFileSystem::unmount() { - if (disk_sync()) + lock(); + if (disk_sync()) { + unlock(); return -1; + } FRESULT res = f_mount(NULL, _fsid, 0); + unlock(); return res == 0 ? 0 : -1; } + +void FATFileSystem::lock() { + _mutex->lock(); +} + +void FATFileSystem::unlock() { + _mutex->unlock(); +}
--- a/FATFileSystem.h Fri Dec 11 16:16:25 2015 +0000 +++ b/FATFileSystem.h Thu Aug 25 09:34:29 2016 +0100 @@ -26,6 +26,7 @@ #include "FileHandle.h" #include "ff.h" #include <stdint.h> +#include "PlatformMutex.h" using namespace mbed; @@ -89,6 +90,15 @@ virtual int disk_sync() { return 0; } virtual uint32_t disk_sectors() = 0; +protected: + + virtual void lock(); + virtual void unlock(); + +private: + + PlatformMutex *_mutex; + }; #endif