forked from premiere/premiere-libtorrent
support locking files
This commit is contained in:
parent
67ad61fd0a
commit
d6c8184381
|
@ -4393,7 +4393,8 @@ struct session_settings
|
|||
bool always_send_user_agent;
|
||||
bool apply_ip_filter_to_trackers;
|
||||
int read_job_every;
|
||||
use_disk_read_ahead;
|
||||
bool use_disk_read_ahead;
|
||||
bool lock_files;
|
||||
};
|
||||
</pre>
|
||||
<p><tt class="docutils literal"><span class="pre">version</span></tt> is automatically set to the libtorrent version you're using
|
||||
|
@ -5115,6 +5116,10 @@ instead pick one read job off of the sorted queue, where <em>x</em> is <tt class
|
|||
<p><tt class="docutils literal"><span class="pre">use_disk_read_ahead</span></tt> defaults to true and will attempt to optimize disk reads
|
||||
by giving the operating system heads up of disk read requests as they are queued
|
||||
in the disk job queue. This gives a significant performance boost for seeding.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">lock_files</span></tt> determines whether or not to lock files which libtorrent is downloading
|
||||
to or seeding from. This is implemented using <tt class="docutils literal"><span class="pre">fcntl(F_SETLK)</span></tt> on unix systems and
|
||||
by not passing in <tt class="docutils literal"><span class="pre">SHARE_READ</span></tt> and <tt class="docutils literal"><span class="pre">SHARE_WRITE</span></tt> on windows. This might prevent
|
||||
3rd party processes from corrupting the files under libtorrent's feet.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="pe-settings">
|
||||
|
|
|
@ -4405,7 +4405,8 @@ session_settings
|
|||
bool always_send_user_agent;
|
||||
bool apply_ip_filter_to_trackers;
|
||||
int read_job_every;
|
||||
use_disk_read_ahead;
|
||||
bool use_disk_read_ahead;
|
||||
bool lock_files;
|
||||
};
|
||||
|
||||
``version`` is automatically set to the libtorrent version you're using
|
||||
|
@ -5274,6 +5275,11 @@ instead pick one read job off of the sorted queue, where *x* is ``read_job_every
|
|||
by giving the operating system heads up of disk read requests as they are queued
|
||||
in the disk job queue. This gives a significant performance boost for seeding.
|
||||
|
||||
``lock_files`` determines whether or not to lock files which libtorrent is downloading
|
||||
to or seeding from. This is implemented using ``fcntl(F_SETLK)`` on unix systems and
|
||||
by not passing in ``SHARE_READ`` and ``SHARE_WRITE`` on windows. This might prevent
|
||||
3rd party processes from corrupting the files under libtorrent's feet.
|
||||
|
||||
pe_settings
|
||||
===========
|
||||
|
||||
|
|
|
@ -182,10 +182,10 @@ namespace libtorrent
|
|||
read_write = 2,
|
||||
rw_mask = read_only | write_only | read_write,
|
||||
no_buffer = 4,
|
||||
mode_mask = rw_mask | no_buffer,
|
||||
sparse = 8,
|
||||
no_atime = 16,
|
||||
random_access = 32,
|
||||
lock_file = 64,
|
||||
|
||||
attribute_hidden = 0x1000,
|
||||
attribute_executable = 0x2000,
|
||||
|
|
|
@ -269,6 +269,7 @@ namespace libtorrent
|
|||
, apply_ip_filter_to_trackers(true)
|
||||
, read_job_every(10)
|
||||
, use_disk_read_ahead(true)
|
||||
, lock_files(false)
|
||||
{}
|
||||
|
||||
// libtorrent version. Used for forward binary compatibility
|
||||
|
@ -1075,6 +1076,10 @@ namespace libtorrent
|
|||
// issue posix_fadvise() or fcntl(F_RDADVISE) for disk reads
|
||||
// ahead of time
|
||||
bool use_disk_read_ahead;
|
||||
|
||||
// if set to true, files will be locked when opened.
|
||||
// preventing any other process from modifying them
|
||||
bool lock_files;
|
||||
};
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
|
60
src/file.cpp
60
src/file.cpp
|
@ -755,29 +755,17 @@ namespace libtorrent
|
|||
struct open_mode_t
|
||||
{
|
||||
DWORD rw_mode;
|
||||
DWORD share_mode;
|
||||
DWORD create_mode;
|
||||
DWORD flags;
|
||||
};
|
||||
|
||||
const static open_mode_t mode_array[] =
|
||||
{
|
||||
// read_only
|
||||
{GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0},
|
||||
{GENERIC_READ, OPEN_EXISTING},
|
||||
// write_only
|
||||
{GENERIC_WRITE, FILE_SHARE_READ, OPEN_ALWAYS, 0},
|
||||
{GENERIC_WRITE, OPEN_ALWAYS},
|
||||
// read_write
|
||||
{GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, 0},
|
||||
// invalid option
|
||||
{0,0,0,0},
|
||||
// read_only no_buffer
|
||||
{GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING },
|
||||
// write_only no_buffer
|
||||
{GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING },
|
||||
// read_write no_buffer
|
||||
{GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING },
|
||||
// invalid option
|
||||
{0,0,0,0}
|
||||
{GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS},
|
||||
};
|
||||
|
||||
const static DWORD attrib_array[] =
|
||||
|
@ -788,6 +776,16 @@ namespace libtorrent
|
|||
FILE_ATTRIBUTE_HIDDEN, // hidden + executable
|
||||
};
|
||||
|
||||
const static DWORD share_array[] =
|
||||
{
|
||||
// read only (no locking)
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
// write only (no locking)
|
||||
FILE_SHARE_READ,
|
||||
// read/write (no locking)
|
||||
FILE_SHARE_READ,
|
||||
};
|
||||
|
||||
#if TORRENT_USE_WSTRING
|
||||
#define CreateFile_ CreateFileW
|
||||
m_path = convert_to_wstring(path);
|
||||
|
@ -797,14 +795,17 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
TORRENT_ASSERT((mode & mode_mask) < sizeof(mode_array)/sizeof(mode_array[0]));
|
||||
open_mode_t const& m = mode_array[mode & mode_mask];
|
||||
open_mode_t const& m = mode_array[mode & rw_mask];
|
||||
DWORD a = attrib_array[(mode & attribute_mask) >> 12];
|
||||
|
||||
DWORD extra_flags = ((mode & random_access) ? FILE_FLAG_RANDOM_ACCESS : 0)
|
||||
| (a ? a : FILE_ATTRIBUTE_NORMAL);
|
||||
DWORD flags
|
||||
= ((mode & random_access) ? FILE_FLAG_RANDOM_ACCESS : 0)
|
||||
| (a ? a : FILE_ATTRIBUTE_NORMAL)
|
||||
| ((mode & no_buffer) ? FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING : 0);
|
||||
|
||||
m_file_handle = CreateFile_(m_path.c_str(), m.rw_mode, m.share_mode, 0
|
||||
, m.create_mode, m.flags | extra_flags, 0);
|
||||
m_file_handle = CreateFile_(m_path.c_str(), m.rw_mode
|
||||
, (mode & lock_file) ? 0 : share_array[mode & rw_mask]
|
||||
, 0, m.create_mode, flags, 0);
|
||||
|
||||
if (m_file_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
@ -869,6 +870,25 @@ namespace libtorrent
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef F_SETLK
|
||||
if (mode & lock_file)
|
||||
{
|
||||
struct flock l =
|
||||
{
|
||||
0, // start offset
|
||||
0, // length (0 = until EOF)
|
||||
getpid(), // owner
|
||||
(mode & write_only) ? F_WRLCK : F_RDLCK, // lock type
|
||||
SEEK_SET // whence
|
||||
};
|
||||
if (fcntl(m_fd, F_SETLK, &l) != 0)
|
||||
{
|
||||
ec.assign(errno, get_posix_category());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DIRECTIO_ON
|
||||
// for solaris
|
||||
if (mode & no_buffer)
|
||||
|
|
|
@ -1382,6 +1382,8 @@ ret:
|
|||
|| (cache_setting == session_settings::disable_os_cache_for_aligned_files
|
||||
&& ((fe->offset + files().file_base(*fe)) & (m_page_size-1)) == 0))
|
||||
mode |= file::no_buffer;
|
||||
bool lock_files = m_settings ? settings().lock_files : false;
|
||||
if (lock_files) mode |= file::lock_file;
|
||||
if (!m_allocate_files) mode |= file::sparse;
|
||||
if (m_settings && settings().no_atime_storage) mode |= file::no_atime;
|
||||
|
||||
|
|
Loading…
Reference in New Issue