mirror of
https://github.com/RetroShare/libretroshare.git
synced 2026-09-14 11:05:45 +05:00
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.
This commit is contained in:
parent
339c765235
commit
f4d1de031f
@ -32,6 +32,7 @@
|
||||
#include <retroshare/rsfiles.h>
|
||||
#include "ft/ftextralist.h"
|
||||
#include "rsitems/rsconfigitems.h"
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "util/rstime.h"
|
||||
#include <stdio.h>
|
||||
@ -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;
|
||||
|
||||
auto ev = std::make_shared<RsSharedDirectoriesEvent>();
|
||||
ev->mEventCode = RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_ADDED;
|
||||
rsEvents->postEvent(ev);
|
||||
IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW);
|
||||
}
|
||||
|
||||
if(rsEvents)
|
||||
{
|
||||
auto ev = std::make_shared<RsSharedDirectoriesEvent>();
|
||||
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<RsSharedDirectoriesEvent>();
|
||||
ev->mEventCode =
|
||||
RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_HASH_FAILED;
|
||||
ev->mFilePath = details.info.path;
|
||||
rsEvents->postEvent(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user