diff options
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py')
-rw-r--r-- | venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py deleted file mode 100644 index d776de5..0000000 --- a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py +++ /dev/null | |||
@@ -1,190 +0,0 @@ | |||
1 | # -*- coding: utf-8 -*- | ||
2 | |||
3 | # pidlockfile.py | ||
4 | # | ||
5 | # Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> | ||
6 | # | ||
7 | # This is free software: you may copy, modify, and/or distribute this work | ||
8 | # under the terms of the Python Software Foundation License, version 2 or | ||
9 | # later as published by the Python Software Foundation. | ||
10 | # No warranty expressed or implied. See the file LICENSE.PSF-2 for details. | ||
11 | |||
12 | """ Lockfile behaviour implemented via Unix PID files. | ||
13 | """ | ||
14 | |||
15 | from __future__ import absolute_import | ||
16 | |||
17 | import errno | ||
18 | import os | ||
19 | import time | ||
20 | |||
21 | from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, | ||
22 | LockTimeout) | ||
23 | |||
24 | |||
25 | class PIDLockFile(LockBase): | ||
26 | """ Lockfile implemented as a Unix PID file. | ||
27 | |||
28 | The lock file is a normal file named by the attribute `path`. | ||
29 | A lock's PID file contains a single line of text, containing | ||
30 | the process ID (PID) of the process that acquired the lock. | ||
31 | |||
32 | >>> lock = PIDLockFile('somefile') | ||
33 | >>> lock = PIDLockFile('somefile') | ||
34 | """ | ||
35 | |||
36 | def __init__(self, path, threaded=False, timeout=None): | ||
37 | # pid lockfiles don't support threaded operation, so always force | ||
38 | # False as the threaded arg. | ||
39 | LockBase.__init__(self, path, False, timeout) | ||
40 | self.unique_name = self.path | ||
41 | |||
42 | def read_pid(self): | ||
43 | """ Get the PID from the lock file. | ||
44 | """ | ||
45 | return read_pid_from_pidfile(self.path) | ||
46 | |||
47 | def is_locked(self): | ||
48 | """ Test if the lock is currently held. | ||
49 | |||
50 | The lock is held if the PID file for this lock exists. | ||
51 | |||
52 | """ | ||
53 | return os.path.exists(self.path) | ||
54 | |||
55 | def i_am_locking(self): | ||
56 | """ Test if the lock is held by the current process. | ||
57 | |||
58 | Returns ``True`` if the current process ID matches the | ||
59 | number stored in the PID file. | ||
60 | """ | ||
61 | return self.is_locked() and os.getpid() == self.read_pid() | ||
62 | |||
63 | def acquire(self, timeout=None): | ||
64 | """ Acquire the lock. | ||
65 | |||
66 | Creates the PID file for this lock, or raises an error if | ||
67 | the lock could not be acquired. | ||
68 | """ | ||
69 | |||
70 | timeout = timeout if timeout is not None else self.timeout | ||
71 | end_time = time.time() | ||
72 | if timeout is not None and timeout > 0: | ||
73 | end_time += timeout | ||
74 | |||
75 | while True: | ||
76 | try: | ||
77 | write_pid_to_pidfile(self.path) | ||
78 | except OSError as exc: | ||
79 | if exc.errno == errno.EEXIST: | ||
80 | # The lock creation failed. Maybe sleep a bit. | ||
81 | if time.time() > end_time: | ||
82 | if timeout is not None and timeout > 0: | ||
83 | raise LockTimeout("Timeout waiting to acquire" | ||
84 | " lock for %s" % | ||
85 | self.path) | ||
86 | else: | ||
87 | raise AlreadyLocked("%s is already locked" % | ||
88 | self.path) | ||
89 | time.sleep(timeout is not None and timeout / 10 or 0.1) | ||
90 | else: | ||
91 | raise LockFailed("failed to create %s" % self.path) | ||
92 | else: | ||
93 | return | ||
94 | |||
95 | def release(self): | ||
96 | """ Release the lock. | ||
97 | |||
98 | Removes the PID file to release the lock, or raises an | ||
99 | error if the current process does not hold the lock. | ||
100 | |||
101 | """ | ||
102 | if not self.is_locked(): | ||
103 | raise NotLocked("%s is not locked" % self.path) | ||
104 | if not self.i_am_locking(): | ||
105 | raise NotMyLock("%s is locked, but not by me" % self.path) | ||
106 | remove_existing_pidfile(self.path) | ||
107 | |||
108 | def break_lock(self): | ||
109 | """ Break an existing lock. | ||
110 | |||
111 | Removes the PID file if it already exists, otherwise does | ||
112 | nothing. | ||
113 | |||
114 | """ | ||
115 | remove_existing_pidfile(self.path) | ||
116 | |||
117 | |||
118 | def read_pid_from_pidfile(pidfile_path): | ||
119 | """ Read the PID recorded in the named PID file. | ||
120 | |||
121 | Read and return the numeric PID recorded as text in the named | ||
122 | PID file. If the PID file cannot be read, or if the content is | ||
123 | not a valid PID, return ``None``. | ||
124 | |||
125 | """ | ||
126 | pid = None | ||
127 | try: | ||
128 | pidfile = open(pidfile_path, 'r') | ||
129 | except IOError: | ||
130 | pass | ||
131 | else: | ||
132 | # According to the FHS 2.3 section on PID files in /var/run: | ||
133 | # | ||
134 | # The file must consist of the process identifier in | ||
135 | # ASCII-encoded decimal, followed by a newline character. | ||
136 | # | ||
137 | # Programs that read PID files should be somewhat flexible | ||
138 | # in what they accept; i.e., they should ignore extra | ||
139 | # whitespace, leading zeroes, absence of the trailing | ||
140 | # newline, or additional lines in the PID file. | ||
141 | |||
142 | line = pidfile.readline().strip() | ||
143 | try: | ||
144 | pid = int(line) | ||
145 | except ValueError: | ||
146 | pass | ||
147 | pidfile.close() | ||
148 | |||
149 | return pid | ||
150 | |||
151 | |||
152 | def write_pid_to_pidfile(pidfile_path): | ||
153 | """ Write the PID in the named PID file. | ||
154 | |||
155 | Get the numeric process ID (“PID”) of the current process | ||
156 | and write it to the named file as a line of text. | ||
157 | |||
158 | """ | ||
159 | open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) | ||
160 | open_mode = 0o644 | ||
161 | pidfile_fd = os.open(pidfile_path, open_flags, open_mode) | ||
162 | pidfile = os.fdopen(pidfile_fd, 'w') | ||
163 | |||
164 | # According to the FHS 2.3 section on PID files in /var/run: | ||
165 | # | ||
166 | # The file must consist of the process identifier in | ||
167 | # ASCII-encoded decimal, followed by a newline character. For | ||
168 | # example, if crond was process number 25, /var/run/crond.pid | ||
169 | # would contain three characters: two, five, and newline. | ||
170 | |||
171 | pid = os.getpid() | ||
172 | pidfile.write("%s\n" % pid) | ||
173 | pidfile.close() | ||
174 | |||
175 | |||
176 | def remove_existing_pidfile(pidfile_path): | ||
177 | """ Remove the named PID file if it exists. | ||
178 | |||
179 | Removing a PID file that doesn't already exist puts us in the | ||
180 | desired state, so we ignore the condition if the file does not | ||
181 | exist. | ||
182 | |||
183 | """ | ||
184 | try: | ||
185 | os.remove(pidfile_path) | ||
186 | except OSError as exc: | ||
187 | if exc.errno == errno.ENOENT: | ||
188 | pass | ||
189 | else: | ||
190 | raise | ||