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 always_send_user_agent;
|
||||||
bool apply_ip_filter_to_trackers;
|
bool apply_ip_filter_to_trackers;
|
||||||
int read_job_every;
|
int read_job_every;
|
||||||
use_disk_read_ahead;
|
bool use_disk_read_ahead;
|
||||||
|
bool lock_files;
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
<p><tt class="docutils literal"><span class="pre">version</span></tt> is automatically set to the libtorrent version you're using
|
<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
|
<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
|
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>
|
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>
|
</div>
|
||||||
<div class="section" id="pe-settings">
|
<div class="section" id="pe-settings">
|
||||||
|
|
|
@ -4405,7 +4405,8 @@ session_settings
|
||||||
bool always_send_user_agent;
|
bool always_send_user_agent;
|
||||||
bool apply_ip_filter_to_trackers;
|
bool apply_ip_filter_to_trackers;
|
||||||
int read_job_every;
|
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
|
``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
|
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.
|
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
|
pe_settings
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|
|
@ -182,10 +182,10 @@ namespace libtorrent
|
||||||
read_write = 2,
|
read_write = 2,
|
||||||
rw_mask = read_only | write_only | read_write,
|
rw_mask = read_only | write_only | read_write,
|
||||||
no_buffer = 4,
|
no_buffer = 4,
|
||||||
mode_mask = rw_mask | no_buffer,
|
|
||||||
sparse = 8,
|
sparse = 8,
|
||||||
no_atime = 16,
|
no_atime = 16,
|
||||||
random_access = 32,
|
random_access = 32,
|
||||||
|
lock_file = 64,
|
||||||
|
|
||||||
attribute_hidden = 0x1000,
|
attribute_hidden = 0x1000,
|
||||||
attribute_executable = 0x2000,
|
attribute_executable = 0x2000,
|
||||||
|
|
|
@ -269,6 +269,7 @@ namespace libtorrent
|
||||||
, apply_ip_filter_to_trackers(true)
|
, apply_ip_filter_to_trackers(true)
|
||||||
, read_job_every(10)
|
, read_job_every(10)
|
||||||
, use_disk_read_ahead(true)
|
, use_disk_read_ahead(true)
|
||||||
|
, lock_files(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// libtorrent version. Used for forward binary compatibility
|
// libtorrent version. Used for forward binary compatibility
|
||||||
|
@ -1075,6 +1076,10 @@ namespace libtorrent
|
||||||
// issue posix_fadvise() or fcntl(F_RDADVISE) for disk reads
|
// issue posix_fadvise() or fcntl(F_RDADVISE) for disk reads
|
||||||
// ahead of time
|
// ahead of time
|
||||||
bool use_disk_read_ahead;
|
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
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
60
src/file.cpp
60
src/file.cpp
|
@ -755,29 +755,17 @@ namespace libtorrent
|
||||||
struct open_mode_t
|
struct open_mode_t
|
||||||
{
|
{
|
||||||
DWORD rw_mode;
|
DWORD rw_mode;
|
||||||
DWORD share_mode;
|
|
||||||
DWORD create_mode;
|
DWORD create_mode;
|
||||||
DWORD flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const static open_mode_t mode_array[] =
|
const static open_mode_t mode_array[] =
|
||||||
{
|
{
|
||||||
// read_only
|
// read_only
|
||||||
{GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0},
|
{GENERIC_READ, OPEN_EXISTING},
|
||||||
// write_only
|
// write_only
|
||||||
{GENERIC_WRITE, FILE_SHARE_READ, OPEN_ALWAYS, 0},
|
{GENERIC_WRITE, OPEN_ALWAYS},
|
||||||
// read_write
|
// read_write
|
||||||
{GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, OPEN_ALWAYS, 0},
|
{GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS},
|
||||||
// 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}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const static DWORD attrib_array[] =
|
const static DWORD attrib_array[] =
|
||||||
|
@ -788,6 +776,16 @@ namespace libtorrent
|
||||||
FILE_ATTRIBUTE_HIDDEN, // hidden + executable
|
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
|
#if TORRENT_USE_WSTRING
|
||||||
#define CreateFile_ CreateFileW
|
#define CreateFile_ CreateFileW
|
||||||
m_path = convert_to_wstring(path);
|
m_path = convert_to_wstring(path);
|
||||||
|
@ -797,14 +795,17 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TORRENT_ASSERT((mode & mode_mask) < sizeof(mode_array)/sizeof(mode_array[0]));
|
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 a = attrib_array[(mode & attribute_mask) >> 12];
|
||||||
|
|
||||||
DWORD extra_flags = ((mode & random_access) ? FILE_FLAG_RANDOM_ACCESS : 0)
|
DWORD flags
|
||||||
| (a ? a : FILE_ATTRIBUTE_NORMAL);
|
= ((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_file_handle = CreateFile_(m_path.c_str(), m.rw_mode
|
||||||
, m.create_mode, m.flags | extra_flags, 0);
|
, (mode & lock_file) ? 0 : share_array[mode & rw_mask]
|
||||||
|
, 0, m.create_mode, flags, 0);
|
||||||
|
|
||||||
if (m_file_handle == INVALID_HANDLE_VALUE)
|
if (m_file_handle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
|
@ -869,6 +870,25 @@ namespace libtorrent
|
||||||
return false;
|
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
|
#ifdef DIRECTIO_ON
|
||||||
// for solaris
|
// for solaris
|
||||||
if (mode & no_buffer)
|
if (mode & no_buffer)
|
||||||
|
|
|
@ -1382,6 +1382,8 @@ ret:
|
||||||
|| (cache_setting == session_settings::disable_os_cache_for_aligned_files
|
|| (cache_setting == session_settings::disable_os_cache_for_aligned_files
|
||||||
&& ((fe->offset + files().file_base(*fe)) & (m_page_size-1)) == 0))
|
&& ((fe->offset + files().file_base(*fe)) & (m_page_size-1)) == 0))
|
||||||
mode |= file::no_buffer;
|
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_allocate_files) mode |= file::sparse;
|
||||||
if (m_settings && settings().no_atime_storage) mode |= file::no_atime;
|
if (m_settings && settings().no_atime_storage) mode |= file::no_atime;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue