(libT) change the API signature for tr_torrentVerify() s.t. client code can be notified when the verify is finished

This commit is contained in:
Jordan Lee 2013-01-31 21:58:25 +00:00
parent 9c550b5a78
commit 69f3e31230
13 changed files with 134 additions and 93 deletions

View File

@ -328,7 +328,7 @@ main (int argc, char ** argv)
if (verify)
{
verify = false;
tr_torrentVerify (tor);
tr_torrentVerify (tor, NULL, NULL);
}
for (;;)

View File

@ -163,7 +163,7 @@ updateTorrent (struct OpenData * o)
tr_torrentSetDownloadDir (o->tor, o->downloadDir);
gtk_widget_set_sensitive (o->file_list, tr_torrentHasMetadata (o->tor));
gtr_file_list_set_torrent (o->file_list, tr_torrentId (o->tor));
tr_torrentVerify (o->tor);
tr_torrentVerify (o->tor, NULL, NULL);
}
}

View File

@ -3,6 +3,6 @@ count=0
while [ $err -eq 0 ]; do
count=$((count+1))
echo starting run number $count
make check
./rename-test
err=$?
done

View File

@ -4,6 +4,7 @@
#include "transmission.h"
#include "platform.h" /* TR_PATH_DELIMETER */
#include "torrent.h"
#include "trevent.h"
#include "libtransmission-test.h"
bool verbose = false;
@ -323,14 +324,6 @@ libtransmission_test_zero_torrent_init (void)
return tor;
}
#define verify_and_block_until_done(tor) \
do { \
do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \
tr_torrentVerify (tor); \
do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \
} while (0)
void
libtransmission_test_zero_torrent_populate (tr_torrent * tor, bool complete)
{
@ -368,10 +361,33 @@ libtransmission_test_zero_torrent_populate (tr_torrent * tor, bool complete)
}
sync ();
verify_and_block_until_done (tor);
libttest_blockingTorrentVerify (tor);
if (complete)
assert (tr_torrentStat(tor)->leftUntilDone == 0);
else
assert (tr_torrentStat(tor)->leftUntilDone == tor->info.pieceSize);
}
/***
****
***/
static void
onVerifyDone (tr_torrent * tor UNUSED, bool aborted UNUSED, void * done)
{
*(bool*)done = true;
}
void
libttest_blockingTorrentVerify (tr_torrent * tor)
{
bool done = false;
assert (session != NULL);
assert (!tr_amInEventThread (session));
tr_torrentVerify (tor, onVerifyDone, &done);
while (!done)
tr_wait_msec (10);
}

View File

@ -81,6 +81,8 @@ void libtransmission_test_session_close (void);
void libtransmission_test_zero_torrent_populate (tr_torrent * tor, bool complete);
tr_torrent * libtransmission_test_zero_torrent_init (void);
void libttest_blockingTorrentVerify (tr_torrent * tor);
#endif /* !LIBTRANSMISSION_TEST_H */

View File

@ -24,13 +24,6 @@
****
***/
#define verify_and_block_until_done(tor) \
do { \
do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \
tr_torrentVerify (tor); \
do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \
} while (0)
static void
zeroes_completeness_func (tr_torrent * torrent UNUSED,
tr_completeness completeness,
@ -122,7 +115,7 @@ test_incomplete_dir_is_subdir_of_download_dir (void)
tr_free (zero_block);
}
verify_and_block_until_done (tor);
libttest_blockingTorrentVerify (tor);
check_int_eq (0, tr_torrentStat(tor)->leftUntilDone);
while ((completeness==completeness_unset) && (time(NULL)<=deadline))

View File

@ -20,13 +20,6 @@
****
***/
#define verify_and_block_until_done(tor) \
do { \
do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \
tr_torrentVerify (tor); \
do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \
} while (0)
#define check_have_none(tor, totalSize) \
do { \
const tr_stat * st = tr_torrentStat(tor); \
@ -172,13 +165,13 @@ test_single_filename_torrent (void)
check (!tor->info.files[0].is_renamed);
/* sanity check the (empty) stats */
verify_and_block_until_done (tor);
libttest_blockingTorrentVerify (tor);
check_have_none (tor, totalSize);
create_single_file_torrent_contents (tor->currentDir);
/* sanity check the stats again, now that we've added the file */
verify_and_block_until_done (tor);
libttest_blockingTorrentVerify (tor);
st = tr_torrentStat (tor);
check_int_eq (TR_STATUS_STOPPED, st->activity);
check_int_eq (TR_STAT_OK, st->error);
@ -328,14 +321,14 @@ test_multifile_torrent (void)
check_streq (expected_files[i], files[i].name);
/* sanity check the (empty) stats */
verify_and_block_until_done (tor);
libttest_blockingTorrentVerify (tor);
check_have_none (tor, totalSize);
/* build the local data */
create_multifile_torrent_contents (tor->currentDir);
/* sanity check the (full) stats */
verify_and_block_until_done (tor);
libttest_blockingTorrentVerify (tor);
st = tr_torrentStat (tor);
check_int_eq (TR_STATUS_STOPPED, st->activity);
check_int_eq (TR_STAT_OK, st->error);
@ -414,7 +407,7 @@ test_multifile_torrent (void)
tr_free (tmp);
tr_free (str);
sync ();
verify_and_block_until_done (tor);
libttest_blockingTorrentVerify (tor);
testFileExistsAndConsistsOfThisString (tor, 0, expected_contents[0]);
for (i=1; i<=2; ++i)
{

View File

@ -395,7 +395,7 @@ torrentVerify (tr_session * session,
for (i = 0; i < torrentCount; ++i)
{
tr_torrent * tor = torrents[i];
tr_torrentVerify (tor);
tr_torrentVerify (tor, NULL, NULL);
notify (session, TR_RPC_TORRENT_CHANGED, tor);
}

View File

@ -918,7 +918,7 @@ torrentInit (tr_torrent * tor, const tr_ctor * ctor)
if (isNewTorrent)
{
tor->startAfterVerify = doStart;
tr_torrentVerify (tor);
tr_torrentVerify (tor, NULL, NULL);
}
else if (doStart)
{
@ -1682,59 +1682,81 @@ tr_torrentStartNow (tr_torrent * tor)
torrentStart (tor, true);
}
static void
torrentRecheckDoneImpl (void * vtor)
struct verify_data
{
tr_torrent * tor = vtor;
assert (tr_isTorrent (tor));
bool aborted;
tr_torrent * tor;
tr_verify_done_func callback_func;
void * callback_data;
};
static void
onVerifyDoneThreadFunc (void * vdata)
{
struct verify_data * data = vdata;
tr_torrent * tor = data->tor;
if (!data->aborted)
tr_torrentRecheckCompleteness (tor);
if (tor->startAfterVerify) {
tor->startAfterVerify = false;
torrentStart (tor, false);
if (data->callback_func != NULL)
(*data->callback_func)(tor, data->aborted, data->callback_data);
if (!data->aborted && tor->startAfterVerify)
{
tor->startAfterVerify = false;
torrentStart (tor, false);
}
tr_free (data);
}
static void
torrentRecheckDoneCB (tr_torrent * tor)
onVerifyDone (tr_torrent * tor, bool aborted, void * vdata)
{
assert (tr_isTorrent (tor));
tr_runInEventThread (tor->session, torrentRecheckDoneImpl, tor);
struct verify_data * data = vdata;
assert (data->tor == tor);
data->aborted = aborted;
tr_runInEventThread (tor->session, onVerifyDoneThreadFunc, data);
}
static void
verifyTorrent (void * vtor)
verifyTorrent (void * vdata)
{
bool startAfter;
tr_torrent * tor = vtor;
bool startAfter;
struct verify_data * data = vdata;
tr_torrent * tor = data->tor;
tr_sessionLock (tor->session);
tr_sessionLock (tor->session);
/* if the torrent's already being verified, stop it */
tr_verifyRemove (tor);
/* if the torrent's already being verified, stop it */
tr_verifyRemove (tor);
startAfter = (tor->isRunning || tor->startAfterVerify) && !tor->isStopping;
if (tor->isRunning)
tr_torrentStop (tor);
tor->startAfterVerify = startAfter;
startAfter = (tor->isRunning || tor->startAfterVerify) && !tor->isStopping;
if (setLocalErrorIfFilesDisappeared (tor))
tor->startAfterVerify = false;
else
tr_verifyAdd (tor, onVerifyDone, data);
if (tor->isRunning)
tr_torrentStop (tor);
tor->startAfterVerify = startAfter;
if (setLocalErrorIfFilesDisappeared (tor))
tor->startAfterVerify = false;
else
tr_verifyAdd (tor, torrentRecheckDoneCB);
tr_sessionUnlock (tor->session);
tr_sessionUnlock (tor->session);
}
void
tr_torrentVerify (tr_torrent * tor)
tr_torrentVerify (tr_torrent * tor,
tr_verify_done_func callback_func,
void * callback_data)
{
if (tr_isTorrent (tor))
tr_runInEventThread (tor->session, verifyTorrent, tor);
struct verify_data * data;
data = tr_new (struct verify_data, 1);
data->tor = tor;
data->aborted = false;
data->callback_func = callback_func;
data->callback_data = callback_data;
tr_runInEventThread (tor->session, verifyTorrent, data);
}
void

View File

@ -1439,7 +1439,7 @@ void tr_torrentClearCompletenessCallback (tr_torrent * torrent);
typedef void (tr_torrent_metadata_func)(tr_torrent * torrent,
void * user_data);
void * user_data);
/**
* Register to be notified whenever a torrent changes from
* having incomplete metadata to having complete metadata.
@ -1722,7 +1722,29 @@ void tr_torrentAmountFinished (const tr_torrent * torrent,
float * tab,
int size);
void tr_torrentVerify (tr_torrent * torrent);
/**
* Callback function invoked when a torrent finishes being verified.
*
* @param torrent the torrent that was verified
* @param aborted true if the verify ended prematurely for some reason,
* such as tr_torrentStop() or tr_torrentSetLocation()
* being called during verification.
* @param callback_data the user-defined pointer from tr_torrentVerify()
*/
typedef void (*tr_verify_done_func)(tr_torrent * torrent,
bool aborted,
void * user_data);
/**
* Queue a torrent for verification.
*
* If callback_func is non-NULL, it will be called from the libtransmission
* thread after the torrent's completness state is updated after the
* file verification pass.
*/
void tr_torrentVerify (tr_torrent * torrent,
tr_verify_done_func callback_func_or_NULL,
void * callback_data_or_NULL);
/***********************************************************************
* tr_info

View File

@ -173,20 +173,12 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag)
struct verify_node
{
tr_torrent * torrent;
tr_verify_done_cb verify_done_cb;
uint64_t current_size;
tr_torrent * torrent;
tr_verify_done_func callback_func;
void * callback_data;
uint64_t current_size;
};
static void
fireCheckDone (tr_torrent * tor, tr_verify_done_cb verify_done_cb)
{
assert (tr_isTorrent (tor));
if (verify_done_cb)
verify_done_cb (tor);
}
static struct verify_node currentNode;
static tr_list * verifyList = NULL;
static tr_thread * verifyThread = NULL;
@ -233,12 +225,11 @@ verifyThreadFunc (void * unused UNUSED)
tr_torrentSetVerifyState (tor, TR_VERIFY_NONE);
assert (tr_isTorrent (tor));
if (!stopCurrent)
{
if (changed)
tr_torrentSetDirty (tor);
fireCheckDone (tor, currentNode.verify_done_cb);
}
if (!stopCurrent && changed)
tr_torrentSetDirty (tor);
if (currentNode.callback_func)
(*currentNode.callback_func)(tor, stopCurrent, currentNode.callback_data);
}
verifyThread = NULL;
@ -266,7 +257,9 @@ compareVerifyByPriorityAndSize (const void * va, const void * vb)
}
void
tr_verifyAdd (tr_torrent * tor, tr_verify_done_cb verify_done_cb)
tr_verifyAdd (tr_torrent * tor,
tr_verify_done_func callback_func,
void * callback_data)
{
struct verify_node * node;
@ -275,7 +268,8 @@ tr_verifyAdd (tr_torrent * tor, tr_verify_done_cb verify_done_cb)
node = tr_new (struct verify_node, 1);
node->torrent = tor;
node->verify_done_cb = verify_done_cb;
node->callback_func = callback_func;
node->callback_data = callback_data;
node->current_size = tr_torrentGetCurrentSizeOnDisk (tor);
tr_lockLock (getVerifyLock ());

View File

@ -22,10 +22,9 @@
* @{
*/
typedef void (*tr_verify_done_cb)(tr_torrent * tor);
void tr_verifyAdd (tr_torrent * tor,
tr_verify_done_cb recheck_done_cb);
void tr_verifyAdd (tr_torrent * tor,
tr_verify_done_func callback_func,
void * callback_user_data);
void tr_verifyRemove (tr_torrent * tor);

View File

@ -406,7 +406,7 @@ int trashDataFile(const char * filename)
- (void) resetCache
{
tr_torrentVerify(fHandle);
tr_torrentVerify(fHandle, NULL, NULL);
[self update];
}