Commit Graph

57 Commits

Author SHA1 Message Date
Kaz Nishimura
4b71b65646 win32: improve the performance of win32.unlink() over CIFS
Emulating POSIX unlink() behavior with os.rename() and os.unlink() is often slow
especially over CIFS from Windows clients due to its protocol overhead. This
patch changes win32.unlink() to try first an exclusive open with the Win32
delete-on-close flag, and if a sharing violation is detected, to fall back to
the original emulation.

This patch also removes a test with os.path.isdir() since we expect opening a
directory shall fail as os.unlink() would.

Example measurements (repeated 3-times after 1-time calibration):

(Without this patch: hg update from null to default)
127 files updated, 0 files merged, 0 files removed, 0 files unresolved
time: real 19.871 secs (user 0.328+0.000 sys 1.794+0.000)
time: real 19.622 secs (user 0.312+0.000 sys 2.044+0.000)
time: real 19.138 secs (user 0.250+0.000 sys 1.872+0.000)

(Without this patch: hg update from default to null)
0 files updated, 0 files merged, 127 files removed, 0 files unresolved
time: real 35.158 secs (user 0.156+0.000 sys 2.512+0.000)
time: real 35.272 secs (user 0.250+0.000 sys 2.512+0.000)
time: real 36.569 secs (user 0.203+0.000 sys 2.387+0.000)

(With this patch: hg update from null to default)
127 files updated, 0 files merged, 0 files removed, 0 files unresolved
time: real 17.893 secs (user 0.328+0.000 sys 1.700+0.000)
time: real 18.512 secs (user 0.265+0.000 sys 1.529+0.000)
time: real 20.238 secs (user 0.312+0.000 sys 1.685+0.000)

(With this patch: hg update from default to null)
0 files updated, 0 files merged, 127 files removed, 0 files unresolved
time: real 12.312 secs (user 0.250+0.000 sys 0.811+0.000)
time: real 12.471 secs (user 0.156+0.000 sys 0.889+0.000)
time: real 9.727 secs (user 0.125+0.000 sys 0.858+0.000)
2013-10-17 13:27:17 +09:00
Simon Heimberg
7b0d35f51c win32: spawndetached returns pid of detached process and not of cmd.exe
win32.spawndetached starts the detached process by `cmd.exe` (or COMSPEC). The
pid it returned was the one of cmd.exe and not the one of the detached process.
When this pid is used to kill the process, the detached process is not killed,
but only cmd.exe.

With this patch the pid of the detached process is written to the pid file.
Killing the process works as expected.

The pid is only evaluated on writing the pid file. It is unnecessary to search
the pid when it is not needed. And more important, it probably does not yet
exist right after the cmd.exe process was started. When the pid is written to
the file, waiting for the start of the detached process has already happened.
Use this functionality instead of writing a 2nd wait function.

Many tests on windows will not fail anymore, all those with the first failing
line "abort: child process failed to start". (The processes still hanging
around from previous test runs have to be killed first. They still block a
tcp port.)
A good test for the functionality of this patch is test-treediscovery.t,
because it starts and kills `hg serve -d` several times.
2014-02-08 14:35:07 +01:00
FUJIWARA Katsunori
79e0e8b442 windows: check target type before actual unlinking to follow POSIX semantics
Creation and writing into target file via vfs (a.k.a opener) is done
after "unlink()" target file, if it exists.

For example, it is assumed that the revision X consists of file 'A',
and the revision Y consists of file 'A/B'. Merging revision X into Y
tries to "unlink()" on directory 'A' of 'A/B', before creation of file
'A'.

On POSIX environment, directories should be removed by "rmdir(2)", and
"unlink(2)" on directories fails. "unlink()" of Mercurial (and Python)
uses "unlink(2)" directly, so unlinking in the merge case above would
fail.

In the other hand, on Windows environment, "unlink()" of Mercurial
tries to rename before actual unlinking, to follow POSIX semantics:
already opened file can be unlinked safely.

This causes unexpected success in unlinking in the merge case above,
even though directory 'A' is renamed to another. This confuses users.

This patch checks whether target is directory or not before renaming,
and raises IOError(errno.EPERM) if so, to follow POSIX semantics.
2013-05-07 05:04:11 +09:00
Mads Kiilerich
b7f720181a check-code: catch trailing space in comments 2013-04-15 01:37:23 +02:00
Augie Fackler
7af5281bfc win32: clean up use of two-argument raise
This makes any attempt to port to Python 3 harder, and the new syntax
is supported in 2.4 already.
2013-01-01 12:50:23 -06:00
Mads Kiilerich
5e3dc3e383 avoid using abbreviations that look like spelling errors 2012-08-27 23:14:27 +02:00
Adrian Buehlmann
bc646a116e win32: remove uneeded usage of _STARTF_USESHOWWINDOW
spawndetached() was the only user of _STARTF_USESHOWWINDOW and it creates the
process with _CREATE_NO_WINDOW anyway. If the process has no window, then
there is nothing to hide.
2012-06-25 19:26:29 +02:00
Adrian Buehlmann
d8571d886c win32: specify _CREATE_NO_WINDOW on spawndetached()
Before this change, a console window briefly popped up on "hg serve -d" and
disappeared again, stealing the focus window (which was very annyoing when
running tests).

Specifying _CREATE_NO_WINDOW instead of _DETACHED_PROCESS fixes this (as tested
on Windows 7 x64).
2012-06-25 19:11:29 +02:00
Adrian Buehlmann
aea748445b win32.py: let samefile and samedevice work on directories too 2012-06-14 11:03:20 +02:00
Adrian Buehlmann
9ecfd4a916 win32: move lookupreg() to windows.py
lookupreg() doesn't use the win32 API directly any more, it uses the Python
standard library module _winreg.
2012-05-27 11:29:52 +02:00
Adrian Buehlmann
dae9e15d0a win32: use Python's _winreg again
This is a partial backout of 7efea3b5db4c.

7efea3b5db4c switched win32.py to using ctypes with the intention to get rid
of the dependency on the pywin32 package.

But 7efea3b5db4c replaced the usage of the Python standard module _winreg in
lookup_reg as well, which was uneeded (note that lookup_reg was later renamed
into lookupreg).

Basically, we're switching back to the previous _winreg-based implementation,
which uses _winreg.QueryValueEx(). QueryValueEx returns a unicode code string.

See also: issue3467
2012-05-27 11:29:45 +02:00
Matt Mackall
d53510c6a2 merge with stable 2012-05-21 16:35:27 -05:00
Matt Mackall
c082b3d973 win32: fix encoding handling for registry strings (issue3467)
This stopped handling non-ASCII strings in 1.8
2012-05-21 16:32:49 -05:00
Brodie Rao
92158e04de cleanup: "raise SomeException()" -> "raise SomeException" 2012-05-12 16:00:58 +02:00
Matt Mackall
ce9126c527 win32: quietly ignore missing CreateHardLinkA for Wine 2011-09-13 17:01:07 -05:00
Adrian Buehlmann
5884f8cd09 win32.py: add argtypes and restype
This is a feature of ctypes. Without these, pypy complains with

  RuntimeWarning: C function without declared arguments called
  RuntimeWarning: C function without declared return type called

As a side effect of specifying restypes, the return value of e.g. CreateFileA
is now implicitly converted to an instance of _HANDLE, so we also need to
change the definition

  _INVALID_HANDLE_VALUE = -1

to

  _INVALID_HANDLE_VALUE = _HANDLE(-1).value

Otherwise, tests for equality to _INVALID_HANDLE_VALUE in code like

  def _getfileinfo(name):
      fh = _kernel32.CreateFileA(name, 0,
              _FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE,
              None, _OPEN_EXISTING, 0, None)
      if fh == _INVALID_HANDLE_VALUE:
          _raiseoserror(name)

would now fail to detect an invalid handle, which in turn would lead to
exceptions raised with wrong errno values, like e.g.

  >>> nlinks('missing.txt')
  Traceback (most recent call last):
  ...
  OSError: [Errno 9] missing.txt: The handle is invalid.

instead of the correct (as per this patch and before it)

  >>> nlinks('missing.txt')
  Traceback (most recent call last):
  ...
  OSError: [Errno 2] missing.txt: The system cannot find the file specified.
2011-05-15 21:33:51 +02:00
Adrian Buehlmann
1301f80255 win32.py: more explicit definition of _STD_ERROR_HANDLE 2011-05-15 21:27:59 +02:00
Adrian Buehlmann
b79bd6d178 rename util.set_signal_handler to setsignalhandler 2011-05-06 15:41:04 +02:00
Adrian Buehlmann
b84ce08e82 rename util.executable_path to executablepath 2011-05-06 15:36:05 +02:00
Adrian Buehlmann
5573dff691 rename util.os_link to oslink 2011-05-06 15:34:34 +02:00
Adrian Buehlmann
554b565228 rename util.lookup_reg to lookupreg 2011-05-06 15:16:22 +02:00
Matt Mackall
c0ef80263c win32: Wine doesn't know about hardlinks 2011-04-21 15:08:48 -05:00
Adrian Buehlmann
92624f7391 set NOT_CONTENT_INDEXED on .hg dir (issue2694)
when running on Windows
2011-03-28 15:54:22 +02:00
Adrian Buehlmann
278d76a89c win32: remove READONLY attribute on unlink 2011-03-27 01:47:58 +01:00
Adrian Buehlmann
e1730e6f6b windows: move unlink to win32.py
no code change
2011-03-27 01:17:48 +01:00
Adrian Buehlmann
5a005c60c3 eliminate win32.user_rcpath_win32() 2011-02-14 11:13:05 +01:00
Adrian Buehlmann
2f13e93b12 win32: move system_rcpath_win32() to windows.py
no code change in system_rcpath_win32

This breaks the dependency from the win32 module on osutil
2011-02-14 11:12:35 +01:00
Adrian Buehlmann
a264a23ffa win32: new function executable_path 2011-02-14 11:12:31 +01:00
Adrian Buehlmann
77ab03f101 port win32.py to using the Python ctypes library
The pywin32 package is no longer needed.

ctypes is now required for running Mercurial on Windows.

ctypes is included in Python since version 2.5. For Python 2.4, ctypes is
available as an extra installer package for Windows.

Moved spawndetached() from windows.py to win32.py and fixed it, using
ctypes as well. spawndetached was defunct with Python 2.6.6 because Python
removed their undocumented subprocess.CreateProcess. This fixes
'hg serve -d' on Windows.
2011-02-14 11:12:26 +01:00
Adrian Buehlmann
9669b3b2bc win32: optimize parameters for the CreateFile call in _getfileinfo
Set dwDesiredAccess to 0 instead of GENERIC_READ.
Zero is  enough for querying the file metadata. We don't even need to
access the -contents- of the file.

Set dwShareMode to FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
instead of the overly restrictive FILE_SHARE_READ.
There is no need to cause write or delete accesses by other processes to
fail while we are querying file metadata.

See http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx
2011-02-14 11:12:22 +01:00
Steve Borho
f5cf898232 win32: win32console.GetStdHandle() can return None
When the Mercurial Python libraries are used within a Windows application with
no console, there is no stderr file handle.
2011-01-21 14:42:15 -06:00
Yuya Nishihara
675210cf34 win32: remove try-catch block of GetModuleFileNameEx (issue2480)
According to the API document, GetModuleFileName is the preferred way to
retrieve the filename of the current process. So we shouldn't try
GetModuleFileName'Ex' first.

Previously system_rcpath_win32() happened to return unicode paths due to
GetModuleFileNameEx (issue2480). This problem is fixed as GetModuleFileName
never return unicode.
2010-11-11 01:12:51 +09:00
Adrian Buehlmann
b1824b07a4 opener: check hardlink count reporting (issue1866)
The Linux CIFS kernel driver (even in 2.6.36) suffers from a hardlink
count blindness bug (lstat() returning 1 in st_nlink when it is expected
to return >1), which causes repository corruption if Mercurial running
on Linux pushes or commits to a hardlinked repository stored on a Windows
share, if that share is mounted using the CIFS driver.

This patch works around issue1866 and improves the workaround done in
65e082ae3076 to fix issue761, by teaching the opener to lazily execute a
runtime check (new function checknlink) to see if the hardlink count
reported by nlinks() can be trusted.

Since nlinks() is also known to return varying count values (1 or >1)
depending on whether the file is open or not and depending on what client
and server software combination is being used for accessing and serving
the Windows share, we deliberately open the file before calling nlinks() in
order to have a stable precondition. Trying to depend on the precondition
"file closed" would be fragile, as the file could have been opened very
easily somewhere else in the program.
2010-11-07 18:21:29 +01:00
Augie Fackler
42c8b2cf07 termwidth: move to ui.ui from util 2010-10-10 10:06:36 -05:00
Matt Mackall
51b3b09c8f backout most of 26e0b9a8ce0d 2010-09-24 12:46:54 -05:00
Brodie Rao
7362459729 cleanup: use x in (a, b) instead of x == a or x == b 2010-09-23 00:02:31 -05:00
Patrick Mezard
efbdac1e61 win32: remove useless lstat() fallback in nlinks()
The fallback was introduced by 33415b0b4e64 at the same time than
nlinks(). Apparently it only handles the case where target path
does not exist. Just raise IOError directly.
2010-08-19 22:51:09 +02:00
Patrick Mezard
5e126e9b42 win32: correctly break hardlinks on network drives (issue761)
win32.nlinks() was often returning 1 instead of the correct
hardlinks count when reading from network drives. This made
commit or push to a repository on a network share to fail
breaking the hardlinks in the datastore, possibly causing
integrity errors in repositories linked locally on the remote
side.

Here is what the MSDN says about GetFileInformationByHandle():

  Depending on the underlying network features of the operating
  system and the type of server connected to, the
  GetFileInformationByHandle function may fail, return partial
  information, or full information for the given file.

In practice, we never got the correct hardlinks count when
reading from and to many combinations of Window XP, 2003, Vista
and 7, via network drives or RDP shares. It always returned 1
instead. The only setup returning an accurate links count was a
samba on Debian.

To avoid this, Mercurial now breaks the hardlinks unconditionally
when writing to a network drive.
2010-08-19 22:51:09 +02:00
Dirkjan Ochtman
cb25b6f79d cleanups: unused variables 2010-06-08 09:30:33 +02:00
Patrick Mezard
88569d9b27 win32: detect console width on Windows
Original version by anatoly techtonik <techtonik@gmail.com>
Following advices from similar bzr code.
2010-04-25 18:27:12 +02:00
Steve Borho
9a5cb3aaab win32: allow hgrc.d on Windows 2010-02-07 05:34:22 -06:00
Matt Mackall
cd3ef170f7 Merge with stable 2010-01-19 22:45:09 -06:00
Matt Mackall
595d66f424 Update license to GPLv2+ 2010-01-19 22:20:08 -06:00
Patrick Mezard
052695b2e4 cmdutil: hide child window created by win32 spawndetached()
Hiding the child process window is not strictly necessary but it avoids opening
an empty shell window when running hg serve as well as a task in the task bar.
The window is hidden after the process is already started causing a single
flicker.
2010-01-10 18:13:34 +01:00
Patrick Mezard
be67c8a241 win32: close file when leaving _getfileinfo() 2010-01-08 23:15:22 +01:00
Siddharth Agarwal
eab3968819 Add support for relinking on Windows.
Test and minor code change by Patrick Mézard <pmezard@gmail.com>
2010-01-08 18:48:39 +05:30
Martin Geisler
ae0794fd45 coding style: use a space after comma
I left a cases like 'lambda x,y:' alone -- the lack of a space does
not bother me as much when the variables are single letters.
2009-07-22 23:12:54 +02:00
Henrik Stuart
97f9be9c1f windows: fix use of undefined exception (issue1707)
This fixes the implied reliance on pywin32 and the win32 module. This
also fixes a regression in fe7c89838a64 that made Mercurial unusable
without pywin32.
2009-06-25 22:43:58 +02:00
Martin Geisler
58e8fb6277 removed unused imports 2009-05-30 23:20:30 +02:00
Sune Foldager
adc90b2605 posixfile: remove posixfile_nt and fix import bug in windows.py
The posixfile_nt class has been superseded by posixfile in osutils.c,
which works on Windows NT and above. All other systems get the regular
python file class which is assigned to posixfile in posix.py (for POSIX)
and in the pure python version of osutils.py (for Win 9x or Windows NT
in pure mode).
2009-05-13 21:36:16 +02:00