From f4d1de031f19936e38d491feba29a0f3bf488b34 Mon Sep 17 00:00:00 2001 From: jolavillette Date: Sun, 16 Aug 2026 17:43:20 +0200 Subject: [PATCH] ft: report a failed extra-file hashing instead of dropping it ftExtraList::hashAFile() only had a success path: when RsDirUtil::hashFile() returned false the file was simply forgotten -- not recorded, no event, not even a log line. Every caller is then left waiting for a hash that will never come, since the file never enters mHashedList and ExtraFileStatus() keeps answering "not ready" forever. The web UI attach dialog turns that into a spinner that cannot be dismissed and one /rsFiles/ExtraFileStatus per second for the rest of the session. hashExtraFile() already refuses missing paths and directories, so reaching the failure means the file was there and still could not be read: permissions, a share unmounted or a file renamed between the check and this thread, an I/O error, or the hashing thread being stopped. Adds RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_HASH_FAILED, carrying the path in the mFilePath field the event already has -- whose comment on mFileHash, "null if error occurred", shows the case was meant to exist. The success event now fills mFilePath and mFileHash too, so a listener can tell which file it is about instead of re-reading the whole extra list. While here, the event is posted outside extMutex rather than under it: posting while holding a service lock invites a deadlock through a handler. --- src/ft/ftextralist.cc | 53 +++++++++++++++++++++++++++++++--------- src/retroshare/rsfiles.h | 1 + 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/ft/ftextralist.cc b/src/ft/ftextralist.cc index 2106dc4d6..f3325cba9 100644 --- a/src/ft/ftextralist.cc +++ b/src/ft/ftextralist.cc @@ -32,6 +32,7 @@ #include #include "ft/ftextralist.h" #include "rsitems/rsconfigitems.h" +#include "util/rsdebug.h" #include "util/rsdir.h" #include "util/rstime.h" #include @@ -99,20 +100,50 @@ void ftExtraList::hashAFile() details.info.path, details.info.fname, details.info.hash, details.info.size )) { - RS_STACK_MUTEX(extMutex); + { + RS_STACK_MUTEX(extMutex); - /* stick it in the available queue */ - mFiles[details.info.hash] = details; - mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash; + /* stick it in the available queue */ + mFiles[details.info.hash] = details; + mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash; - /* add to the path->hash map */ - mHashedList[details.info.path] = details.info.hash; - - IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); + /* add to the path->hash map */ + mHashedList[details.info.path] = details.info.hash; + + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); + } - auto ev = std::make_shared(); - ev->mEventCode = RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_ADDED; - rsEvents->postEvent(ev); + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mEventCode = RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_ADDED; + ev->mFilePath = details.info.path; + ev->mFileHash = details.info.hash; + rsEvents->postEvent(ev); + } + } + else + { + /* hashExtraFile() has already refused the paths that do not exist and + * the directories, so reaching here means the file was there and could + * still not be read: permissions, a share unmounted or a file renamed + * between the two, an I/O error, or this thread being stopped. + * + * Failing silently leaves every caller waiting for a hash that will + * never come -- the file never enters mHashedList, so ExtraFileStatus() + * keeps answering "not ready" forever, and the web UI attach dialog + * polls it once a second for the rest of the session. */ + RsErr() << __PRETTY_FUNCTION__ << " failed to hash " << details.info.path + << ", it will not be added to the extra list" << std::endl; + + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mEventCode = + RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_HASH_FAILED; + ev->mFilePath = details.info.path; + rsEvents->postEvent(ev); + } } } diff --git a/src/retroshare/rsfiles.h b/src/retroshare/rsfiles.h index 91e9a786e..363051212 100644 --- a/src/retroshare/rsfiles.h +++ b/src/retroshare/rsfiles.h @@ -192,6 +192,7 @@ enum class RsSharedDirectoriesEventCode: uint8_t { FRIEND_DIR_LIST_UPDATED = 0x0b, // NOTIFY_LIST_DIRLIST_FRIENDS, friend dir list has been updated OWN_DIR_LIST_UPDATED = 0x0c, // NOTIFY_LIST_DIRLIST_LOCAL , own dir list has been updated OWN_DIR_LIST_PROCESSING = 0x0d, // NOTIFY_LIST_DIRLIST_LOCAL prechange + EXTRA_LIST_FILE_HASH_FAILED = 0x0e, // mFilePath: file that could not be hashed, mFileHash null }; enum class RsFileTransferEventCode: uint8_t {