This commit is contained in:
Kovid Goyal 2020-11-02 18:11:59 +05:30
parent 786f3e963e
commit 0f590b1e20
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 19 additions and 20 deletions

View File

@ -10,15 +10,13 @@ import os
import re
import shutil
import sys
import time
import unicodedata
import uuid
from collections import defaultdict
from css_parser import getUrls, replaceUrls
from io import BytesIO
from itertools import count
from css_parser import getUrls, replaceUrls
from calibre import CurrentDir, walk
from calibre.constants import iswindows
from calibre.customize.ui import plugin_for_input_format, plugin_for_output_format
@ -48,7 +46,7 @@ from calibre.ebooks.oeb.polish.utils import (
CommentFinder, PositionFinder, guess_type, parse_css
)
from calibre.ptempfile import PersistentTemporaryDirectory, PersistentTemporaryFile
from calibre.utils.filenames import hardlink_file, nlinks_file
from calibre.utils.filenames import hardlink_file, nlinks_file, retry_on_fail
from calibre.utils.ipc.simple_worker import WorkerError, fork_job
from calibre.utils.logging import default_log
from calibre.utils.xml_parse import safe_xml_fromstring
@ -1057,12 +1055,9 @@ class Container(ContainerBase): # {{{
# Decouple this file from its links
temp = path + 'xxx'
shutil.copyfile(path, temp)
try:
os.unlink(path)
except EnvironmentError:
if not iswindows:
raise
time.sleep(1) # Wait for whatever has locked the file to release it
if iswindows:
retry_on_fail(os.unlink, path)
else:
os.unlink(path)
os.rename(temp, path)
return path

View File

@ -466,21 +466,25 @@ if iswindows:
move_file(a, b)
def retry_on_fail(func, *args, count=10, sleep_time=0.2):
for i in range(count):
try:
func(*args)
break
except OSError:
if i > count - 2:
raise
# Try the operation repeatedly in case something like a virus
# scanner has opened one of the files (I love windows)
time.sleep(sleep_time)
def atomic_rename(oldpath, newpath):
'''Replace the file newpath with the file oldpath. Can fail if the files
are on different volumes. If succeeds, guaranteed to be atomic. newpath may
or may not exist. If it exists, it is replaced. '''
if iswindows:
for i in range(10):
try:
rename_file(oldpath, newpath)
break
except Exception:
if i > 8:
raise
# Try the rename repeatedly in case something like a virus
# scanner has opened one of the files (I love windows)
time.sleep(1)
retry_on_fail(rename_file, oldpath, newpath)
else:
os.rename(oldpath, newpath)