source: trunk/libtransmission/torrent.h @ 11706

Last change on this file since 11706 was 11706, checked in by jordan, 11 years ago

cleanup of who calls the libtransmission thread locking functions.

In some cases we were calling them from deep inside libtransmission, when they should have been called directly from the public-visible API functions: tr_torrentWebSpeeds_KBps(), tr_torrentPeers(), tr_torrentTrackers().

  • Property svn:keywords set to Date Rev Author Id
File size: 13.4 KB
Line 
1/*
2 * This file Copyright (C) 2009-2010 Mnemosyne LLC
3 *
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: torrent.h 11706 2011-01-18 23:44:36Z jordan $
11 */
12
13#ifndef __TRANSMISSION__
14 #error only libtransmission should #include this header.
15#endif
16
17#ifndef TR_TORRENT_H
18#define TR_TORRENT_H 1
19
20#include "completion.h" /* tr_completion */
21#include "session.h" /* tr_sessionLock(), tr_sessionUnlock() */
22#include "utils.h" /* TR_GNUC_PRINTF */
23
24struct tr_bandwidth;
25struct tr_torrent_tiers;
26struct tr_magnet_info;
27
28/**
29***  Package-visible ctor API
30**/
31
32void        tr_ctorSetSave( tr_ctor * ctor,
33                            tr_bool   saveMetadataInOurTorrentsDir );
34
35int         tr_ctorGetSave( const tr_ctor * ctor );
36
37void        tr_ctorInitTorrentPriorities( const tr_ctor * ctor, tr_torrent * tor );
38
39void        tr_ctorInitTorrentWanted( const tr_ctor * ctor, tr_torrent * tor );
40
41/**
42***
43**/
44
45/* just like tr_torrentSetFileDLs but doesn't trigger a fastresume save */
46void        tr_torrentInitFileDLs( tr_torrent              * tor,
47                                   const tr_file_index_t   * files,
48                                   tr_file_index_t          fileCount,
49                                   tr_bool                  do_download );
50
51void        tr_torrentRecheckCompleteness( tr_torrent * );
52
53void        tr_torrentSetHasPiece( tr_torrent *     tor,
54                                   tr_piece_index_t pieceIndex,
55                                   tr_bool          has );
56
57void        tr_torrentChangeMyPort( tr_torrent * session );
58
59tr_torrent* tr_torrentFindFromHashString( tr_session * session,
60                                          const char * hashString );
61
62tr_torrent* tr_torrentFindFromObfuscatedHash( tr_session    * session,
63                                              const uint8_t * hash );
64
65tr_bool     tr_torrentIsPieceTransferAllowed( const tr_torrent * torrent,
66                                              tr_direction       direction );
67
68
69
70#define tr_block( a, b ) _tr_block( tor, a, b )
71tr_block_index_t _tr_block( const tr_torrent * tor,
72                            tr_piece_index_t   index,
73                            uint32_t           offset );
74
75tr_bool          tr_torrentReqIsValid( const tr_torrent * tor,
76                                       tr_piece_index_t   index,
77                                       uint32_t           offset,
78                                       uint32_t           length );
79
80uint64_t         tr_pieceOffset( const tr_torrent * tor,
81                                 tr_piece_index_t   index,
82                                 uint32_t           offset,
83                                 uint32_t           length );
84
85void             tr_torrentInitFilePriority( tr_torrent       * tor,
86                                             tr_file_index_t    fileIndex,
87                                             tr_priority_t      priority );
88
89void             tr_torrentSetPieceChecked( tr_torrent       * tor,
90                                            tr_piece_index_t   piece );
91
92void             tr_torrentSetChecked( tr_torrent * tor, time_t when );
93
94tr_torrent*      tr_torrentNext( tr_session  * session,
95                                 tr_torrent  * current );
96
97void             tr_torrentCheckSeedLimit( tr_torrent * tor );
98
99/** save a torrent's .resume file if it's changed since the last time it was saved */
100void             tr_torrentSave( tr_torrent * tor );
101
102void             tr_torrentSetLocalError( tr_torrent * tor, const char * fmt, ... ) TR_GNUC_PRINTF( 2, 3 );
103
104
105
106typedef enum
107{
108    TR_VERIFY_NONE,
109    TR_VERIFY_WAIT,
110    TR_VERIFY_NOW
111}
112tr_verify_state;
113
114void             tr_torrentSetVerifyState( tr_torrent      * tor,
115                                           tr_verify_state   state );
116
117tr_torrent_activity tr_torrentGetActivity( tr_torrent * tor );
118
119struct tr_incomplete_metadata;
120
121/** @brief Torrent object */
122struct tr_torrent
123{
124    tr_session *             session;
125    tr_info                  info;
126
127    int                      magicNumber;
128
129    tr_stat_errtype          error;
130    char                     errorString[128];
131    char                     errorTracker[128];
132
133    uint8_t                  obfuscatedHash[SHA_DIGEST_LENGTH];
134
135    /* Used when the torrent has been created with a magnet link
136     * and we're in the process of downloading the metainfo from
137     * other peers */
138    struct tr_incomplete_metadata  * incompleteMetadata;
139
140    /* If the initiator of the connection receives a handshake in which the
141     * peer_id does not match the expected peerid, then the initiator is
142     * expected to drop the connection. Note that the initiator presumably
143     * received the peer information from the tracker, which includes the
144     * peer_id that was registered by the peer. The peer_id from the tracker
145     * and in the handshake are expected to match.
146     */
147    uint8_t * peer_id;
148
149    /* Where the files will be when it's complete */
150    char * downloadDir;
151
152    /* Where the files are when the torrent is incomplete */
153    char * incompleteDir;
154
155    /* Length, in bytes, of the "info" dict in the .torrent file. */
156    int infoDictLength;
157
158    /* Offset, in bytes, of the beginning of the "info" dict in the .torrent file.
159     *
160     * Used by the torrent-magnet code for serving metainfo to peers.
161     * This field is lazy-generated and might not be initialized yet. */
162    int infoDictOffset;
163
164    /* Where the files are now.
165     * This pointer will be equal to downloadDir or incompleteDir */
166    const char * currentDir;
167
168    /* How many bytes we ask for per request */
169    uint32_t                   blockSize;
170    tr_block_index_t           blockCount;
171
172    uint32_t                   lastBlockSize;
173    uint32_t                   lastPieceSize;
174
175    uint16_t                   blockCountInPiece;
176    uint16_t                   blockCountInLastPiece;
177
178    struct tr_completion       completion;
179
180    tr_completeness            completeness;
181
182    struct tr_torrent_tiers  * tiers;
183
184    time_t                     dhtAnnounceAt;
185    time_t                     dhtAnnounce6At;
186    tr_bool                    dhtAnnounceInProgress;
187    tr_bool                    dhtAnnounce6InProgress;
188
189    time_t                     lpdAnnounceAt;
190
191    uint64_t                   downloadedCur;
192    uint64_t                   downloadedPrev;
193    uint64_t                   uploadedCur;
194    uint64_t                   uploadedPrev;
195    uint64_t                   corruptCur;
196    uint64_t                   corruptPrev;
197
198    uint64_t                   etaDLSpeedCalculatedAt;
199    double                     etaDLSpeed_KBps;
200    uint64_t                   etaULSpeedCalculatedAt;
201    double                     etaULSpeed_KBps;
202
203    time_t                     addedDate;
204    time_t                     activityDate;
205    time_t                     doneDate;
206    time_t                     startDate;
207    time_t                     anyDate;
208
209    time_t                     secondsDownloading;
210    time_t                     secondsSeeding;
211
212    tr_torrent_metadata_func  * metadata_func;
213    void                      * metadata_func_user_data;
214
215    tr_torrent_completeness_func  * completeness_func;
216    void                          *  completeness_func_user_data;
217
218    tr_torrent_ratio_limit_hit_func  * ratio_limit_hit_func;
219    void                             * ratio_limit_hit_func_user_data;
220
221    tr_torrent_idle_limit_hit_func  * idle_limit_hit_func;
222    void                            * idle_limit_hit_func_user_data;
223
224    tr_bool                    isRunning;
225    tr_bool                    isStopping;
226    tr_bool                    isDeleting;
227    tr_bool                    startAfterVerify;
228    tr_bool                    isDirty;
229
230    tr_bool                    infoDictOffsetIsCached;
231
232    uint16_t                   maxConnectedPeers;
233
234    tr_verify_state            verifyState;
235
236    time_t                     lastStatTime;
237    tr_stat                    stats;
238
239    tr_torrent *               next;
240
241    int                        uniqueId;
242
243    struct tr_bandwidth      * bandwidth;
244
245    struct tr_torrent_peers  * torrentPeers;
246
247    double                     desiredRatio;
248    tr_ratiolimit              ratioLimitMode;
249
250    uint16_t                   idleLimitMinutes;
251    tr_idlelimit               idleLimitMode;
252    tr_bool                    finishedSeedingByIdle;
253};
254
255/* get the index of this piece's first block */
256static inline tr_block_index_t
257tr_torPieceFirstBlock( const tr_torrent * tor, const tr_piece_index_t piece )
258{
259    return piece * tor->blockCountInPiece;
260}
261
262/* what piece index is this block in? */
263static inline tr_piece_index_t
264tr_torBlockPiece( const tr_torrent * tor, const tr_block_index_t block )
265{
266    return block / tor->blockCountInPiece;
267}
268
269/* how many blocks are in this piece? */
270static inline uint16_t
271tr_torPieceCountBlocks( const tr_torrent * tor, const tr_piece_index_t piece )
272{
273    if( piece + 1 == tor->info.pieceCount )
274        return tor->blockCountInLastPiece;
275    else
276        return tor->blockCountInPiece;
277}
278
279/* how many bytes are in this piece? */
280static inline uint32_t
281tr_torPieceCountBytes( const tr_torrent * tor, const tr_piece_index_t piece )
282{
283    return piece == tor->info.pieceCount - 1 ? tor->lastPieceSize
284                                             : tor->info.pieceSize;
285}
286
287/* how many bytes are in this block? */
288static inline uint32_t
289tr_torBlockCountBytes( const tr_torrent * tor, const tr_block_index_t block )
290{
291    return block == tor->blockCount - 1 ? tor->lastBlockSize
292                                        : tor->blockSize;
293}
294
295static inline void tr_torrentLock( const tr_torrent * tor )
296{
297    tr_sessionLock( tor->session );
298}
299
300static inline tr_bool tr_torrentIsLocked( const tr_torrent * tor )
301{
302    return tr_sessionIsLocked( tor->session );
303}
304
305static inline void tr_torrentUnlock( const tr_torrent * tor )
306{
307    tr_sessionUnlock( tor->session );
308}
309
310static inline tr_bool
311tr_torrentExists( const tr_session * session, const uint8_t *   torrentHash )
312{
313    return tr_torrentFindFromHash( (tr_session*)session, torrentHash ) != NULL;
314}
315
316static inline tr_bool
317tr_torrentIsSeed( const tr_torrent * tor )
318{
319    return tor->completeness != TR_LEECH;
320}
321
322static inline tr_bool tr_torrentIsPrivate( const tr_torrent * tor )
323{
324    return ( tor != NULL ) && tor->info.isPrivate;
325}
326
327static inline tr_bool tr_torrentAllowsPex( const tr_torrent * tor )
328{
329    return ( tor != NULL )
330        && ( tor->session->isPexEnabled )
331        && ( !tr_torrentIsPrivate( tor ) );
332}
333
334static inline tr_bool tr_torrentAllowsDHT( const tr_torrent * tor )
335{
336    return ( tor != NULL )
337        && ( tr_sessionAllowsDHT( tor->session ) )
338        && ( !tr_torrentIsPrivate( tor ) );
339}
340
341static inline tr_bool tr_torrentAllowsLPD( const tr_torrent * tor )
342{
343    return ( tor != NULL )
344        && ( tr_sessionAllowsLPD( tor->session ) )
345        && ( !tr_torrentIsPrivate( tor ) );
346}
347
348/***
349****
350***/
351
352enum
353{
354    TORRENT_MAGIC_NUMBER = 95549
355};
356
357static inline tr_bool tr_isTorrent( const tr_torrent * tor )
358{
359    return ( tor != NULL )
360        && ( tor->magicNumber == TORRENT_MAGIC_NUMBER )
361        && ( tr_isSession( tor->session ) );
362}
363
364/* set a flag indicating that the torrent's .resume file
365 * needs to be saved when the torrent is closed */
366static inline
367void tr_torrentSetDirty( tr_torrent * tor )
368{
369    assert( tr_isTorrent( tor ) );
370
371    tor->isDirty = TRUE;
372}
373
374static inline
375const char * tr_torrentName( const tr_torrent * tor )
376{
377    assert( tr_isTorrent( tor ) );
378
379    return tor->info.name;
380}
381
382uint32_t tr_getBlockSize( uint32_t pieceSize );
383
384/**
385 * Tell the tr_torrent that one of its files has become complete
386 */
387void tr_torrentFileCompleted( tr_torrent * tor, tr_file_index_t fileNo );
388
389
390/**
391 * @brief Like tr_torrentFindFile(), but splits the filename into base and subpath;
392 *
393 * If the file is found, "tr_buildPath( base, subpath, NULL )"
394 * will generate the complete filename.
395 *
396 * @return true if the file is found, false otherwise.
397 *
398 * @param base if the torrent is found, this will be either
399 *             tor->downloadDir or tor->incompleteDir
400 * @param subpath on success, this pointer is assigned a newly-allocated
401 *                string holding the second half of the filename.
402 */
403tr_bool tr_torrentFindFile2( const tr_torrent *, tr_file_index_t fileNo,
404                             const char ** base, char ** subpath );
405
406
407/* Returns a newly-allocated version of the tr_file.name string
408 * that's been modified to denote that it's not a complete file yet.
409 * In the current implementation this is done by appending ".part"
410 * a la Firefox. */
411char* tr_torrentBuildPartial( const tr_torrent *, tr_file_index_t fileNo );
412
413/* for when the info dict has been fundamentally changed wrt files,
414 * piece size, etc. such as in BEP 9 where peers exchange metadata */
415void tr_torrentGotNewInfoDict( tr_torrent * tor );
416
417void tr_torrentSetSpeedLimit_Bps  ( tr_torrent *, tr_direction, int Bps );
418int tr_torrentGetSpeedLimit_Bps  ( const tr_torrent *, tr_direction );
419
420/**
421 * @return true if this piece needs to be tested
422 */
423tr_bool tr_torrentPieceNeedsCheck( const tr_torrent * tor, tr_piece_index_t pieceIndex );
424
425/**
426 * @brief Test a piece against its info dict checksum
427 * @return true if the piece's passes the checksum test
428 */
429tr_bool tr_torrentCheckPiece( tr_torrent * tor, tr_piece_index_t pieceIndex );
430
431uint64_t tr_torrentGetCurrentSizeOnDisk( const tr_torrent * tor );
432
433
434#endif
Note: See TracBrowser for help on using the repository browser.