##// END OF EJS Templates
moved kill function to compat
marcink -
r1549:d6cb805c beta
parent child Browse files
Show More
@@ -1,360 +1,379 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.lib.compat
4 4 ~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Python backward compatibility functions and common libs
7 7
8 8
9 9 :created_on: Oct 7, 2011
10 10 :author: marcink
11 11 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
12 12 :license: GPLv3, see COPYING for more details.
13 13 """
14 14 # This program is free software: you can redistribute it and/or modify
15 15 # it under the terms of the GNU General Public License as published by
16 16 # the Free Software Foundation, either version 3 of the License, or
17 17 # (at your option) any later version.
18 18 #
19 19 # This program is distributed in the hope that it will be useful,
20 20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 22 # GNU General Public License for more details.
23 23 #
24 24 # You should have received a copy of the GNU General Public License
25 25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26
27 import os
28 from rhodecode import __platform__, PLATFORM_WIN
29
27 30 #==============================================================================
28 31 # json
29 32 #==============================================================================
30 33 try:
31 34 import json
32 35 except ImportError:
33 36 import simplejson as json
34 37
35 38
36 39 #==============================================================================
37 40 # izip_longest
38 41 #==============================================================================
39 42 try:
40 43 from itertools import izip_longest
41 44 except ImportError:
42 45 import itertools
43 46
44 47 def izip_longest(*args, **kwds): # noqa
45 48 fillvalue = kwds.get("fillvalue")
46 49
47 50 def sentinel(counter=([fillvalue] * (len(args) - 1)).pop):
48 51 yield counter() # yields the fillvalue, or raises IndexError
49 52
50 53 fillers = itertools.repeat(fillvalue)
51 54 iters = [itertools.chain(it, sentinel(), fillers)
52 55 for it in args]
53 56 try:
54 57 for tup in itertools.izip(*iters):
55 58 yield tup
56 59 except IndexError:
57 60 pass
58 61
59 62
60 63 #==============================================================================
61 64 # OrderedDict
62 65 #==============================================================================
63 66
64 67 # Python Software Foundation License
65 68
66 69 # XXX: it feels like using the class with "is" and "is not" instead of "==" and
67 70 # "!=" should be faster.
68 71 class _Nil(object):
69 72
70 73 def __repr__(self):
71 74 return "nil"
72 75
73 76 def __eq__(self, other):
74 77 if (isinstance(other, _Nil)):
75 78 return True
76 79 else:
77 80 return NotImplemented
78 81
79 82 def __ne__(self, other):
80 83 if (isinstance(other, _Nil)):
81 84 return False
82 85 else:
83 86 return NotImplemented
84 87
85 88 _nil = _Nil()
86 89
87 90 class _odict(object):
88 91 """Ordered dict data structure, with O(1) complexity for dict operations
89 92 that modify one element.
90 93
91 94 Overwriting values doesn't change their original sequential order.
92 95 """
93 96
94 97 def _dict_impl(self):
95 98 return None
96 99
97 100 def __init__(self, data=(), **kwds):
98 101 """This doesn't accept keyword initialization as normal dicts to avoid
99 102 a trap - inside a function or method the keyword args are accessible
100 103 only as a dict, without a defined order, so their original order is
101 104 lost.
102 105 """
103 106 if kwds:
104 107 raise TypeError("__init__() of ordered dict takes no keyword "
105 108 "arguments to avoid an ordering trap.")
106 109 self._dict_impl().__init__(self)
107 110 # If you give a normal dict, then the order of elements is undefined
108 111 if hasattr(data, "iteritems"):
109 112 for key, val in data.iteritems():
110 113 self[key] = val
111 114 else:
112 115 for key, val in data:
113 116 self[key] = val
114 117
115 118 # Double-linked list header
116 119 def _get_lh(self):
117 120 dict_impl = self._dict_impl()
118 121 if not hasattr(self, '_lh'):
119 122 dict_impl.__setattr__(self, '_lh', _nil)
120 123 return dict_impl.__getattribute__(self, '_lh')
121 124
122 125 def _set_lh(self, val):
123 126 self._dict_impl().__setattr__(self, '_lh', val)
124 127
125 128 lh = property(_get_lh, _set_lh)
126 129
127 130 # Double-linked list tail
128 131 def _get_lt(self):
129 132 dict_impl = self._dict_impl()
130 133 if not hasattr(self, '_lt'):
131 134 dict_impl.__setattr__(self, '_lt', _nil)
132 135 return dict_impl.__getattribute__(self, '_lt')
133 136
134 137 def _set_lt(self, val):
135 138 self._dict_impl().__setattr__(self, '_lt', val)
136 139
137 140 lt = property(_get_lt, _set_lt)
138 141
139 142 def __getitem__(self, key):
140 143 return self._dict_impl().__getitem__(self, key)[1]
141 144
142 145 def __setitem__(self, key, val):
143 146 dict_impl = self._dict_impl()
144 147 try:
145 148 dict_impl.__getitem__(self, key)[1] = val
146 149 except KeyError, e:
147 150 new = [dict_impl.__getattribute__(self, 'lt'), val, _nil]
148 151 dict_impl.__setitem__(self, key, new)
149 152 if dict_impl.__getattribute__(self, 'lt') == _nil:
150 153 dict_impl.__setattr__(self, 'lh', key)
151 154 else:
152 155 dict_impl.__getitem__(
153 156 self, dict_impl.__getattribute__(self, 'lt'))[2] = key
154 157 dict_impl.__setattr__(self, 'lt', key)
155 158
156 159 def __delitem__(self, key):
157 160 dict_impl = self._dict_impl()
158 161 pred, _ , succ = self._dict_impl().__getitem__(self, key)
159 162 if pred == _nil:
160 163 dict_impl.__setattr__(self, 'lh', succ)
161 164 else:
162 165 dict_impl.__getitem__(self, pred)[2] = succ
163 166 if succ == _nil:
164 167 dict_impl.__setattr__(self, 'lt', pred)
165 168 else:
166 169 dict_impl.__getitem__(self, succ)[0] = pred
167 170 dict_impl.__delitem__(self, key)
168 171
169 172 def __contains__(self, key):
170 173 return key in self.keys()
171 174
172 175 def __len__(self):
173 176 return len(self.keys())
174 177
175 178 def __str__(self):
176 179 pairs = ("%r: %r" % (k, v) for k, v in self.iteritems())
177 180 return "{%s}" % ", ".join(pairs)
178 181
179 182 def __repr__(self):
180 183 if self:
181 184 pairs = ("(%r, %r)" % (k, v) for k, v in self.iteritems())
182 185 return "odict([%s])" % ", ".join(pairs)
183 186 else:
184 187 return "odict()"
185 188
186 189 def get(self, k, x=None):
187 190 if k in self:
188 191 return self._dict_impl().__getitem__(self, k)[1]
189 192 else:
190 193 return x
191 194
192 195 def __iter__(self):
193 196 dict_impl = self._dict_impl()
194 197 curr_key = dict_impl.__getattribute__(self, 'lh')
195 198 while curr_key != _nil:
196 199 yield curr_key
197 200 curr_key = dict_impl.__getitem__(self, curr_key)[2]
198 201
199 202 iterkeys = __iter__
200 203
201 204 def keys(self):
202 205 return list(self.iterkeys())
203 206
204 207 def itervalues(self):
205 208 dict_impl = self._dict_impl()
206 209 curr_key = dict_impl.__getattribute__(self, 'lh')
207 210 while curr_key != _nil:
208 211 _, val, curr_key = dict_impl.__getitem__(self, curr_key)
209 212 yield val
210 213
211 214 def values(self):
212 215 return list(self.itervalues())
213 216
214 217 def iteritems(self):
215 218 dict_impl = self._dict_impl()
216 219 curr_key = dict_impl.__getattribute__(self, 'lh')
217 220 while curr_key != _nil:
218 221 _, val, next_key = dict_impl.__getitem__(self, curr_key)
219 222 yield curr_key, val
220 223 curr_key = next_key
221 224
222 225 def items(self):
223 226 return list(self.iteritems())
224 227
225 228 def sort(self, cmp=None, key=None, reverse=False):
226 229 items = [(k, v) for k, v in self.items()]
227 230 if cmp is not None:
228 231 items = sorted(items, cmp=cmp)
229 232 elif key is not None:
230 233 items = sorted(items, key=key)
231 234 else:
232 235 items = sorted(items, key=lambda x: x[1])
233 236 if reverse:
234 237 items.reverse()
235 238 self.clear()
236 239 self.__init__(items)
237 240
238 241 def clear(self):
239 242 dict_impl = self._dict_impl()
240 243 dict_impl.clear(self)
241 244 dict_impl.__setattr__(self, 'lh', _nil)
242 245 dict_impl.__setattr__(self, 'lt', _nil)
243 246
244 247 def copy(self):
245 248 return self.__class__(self)
246 249
247 250 def update(self, data=(), **kwds):
248 251 if kwds:
249 252 raise TypeError("update() of ordered dict takes no keyword "
250 253 "arguments to avoid an ordering trap.")
251 254 if hasattr(data, "iteritems"):
252 255 data = data.iteritems()
253 256 for key, val in data:
254 257 self[key] = val
255 258
256 259 def setdefault(self, k, x=None):
257 260 try:
258 261 return self[k]
259 262 except KeyError:
260 263 self[k] = x
261 264 return x
262 265
263 266 def pop(self, k, x=_nil):
264 267 try:
265 268 val = self[k]
266 269 del self[k]
267 270 return val
268 271 except KeyError:
269 272 if x == _nil:
270 273 raise
271 274 return x
272 275
273 276 def popitem(self):
274 277 try:
275 278 dict_impl = self._dict_impl()
276 279 key = dict_impl.__getattribute__(self, 'lt')
277 280 return key, self.pop(key)
278 281 except KeyError:
279 282 raise KeyError("'popitem(): ordered dictionary is empty'")
280 283
281 284 def riterkeys(self):
282 285 """To iterate on keys in reversed order.
283 286 """
284 287 dict_impl = self._dict_impl()
285 288 curr_key = dict_impl.__getattribute__(self, 'lt')
286 289 while curr_key != _nil:
287 290 yield curr_key
288 291 curr_key = dict_impl.__getitem__(self, curr_key)[0]
289 292
290 293 __reversed__ = riterkeys
291 294
292 295 def rkeys(self):
293 296 """List of the keys in reversed order.
294 297 """
295 298 return list(self.riterkeys())
296 299
297 300 def ritervalues(self):
298 301 """To iterate on values in reversed order.
299 302 """
300 303 dict_impl = self._dict_impl()
301 304 curr_key = dict_impl.__getattribute__(self, 'lt')
302 305 while curr_key != _nil:
303 306 curr_key, val, _ = dict_impl.__getitem__(self, curr_key)
304 307 yield val
305 308
306 309 def rvalues(self):
307 310 """List of the values in reversed order.
308 311 """
309 312 return list(self.ritervalues())
310 313
311 314 def riteritems(self):
312 315 """To iterate on (key, value) in reversed order.
313 316 """
314 317 dict_impl = self._dict_impl()
315 318 curr_key = dict_impl.__getattribute__(self, 'lt')
316 319 while curr_key != _nil:
317 320 pred_key, val, _ = dict_impl.__getitem__(self, curr_key)
318 321 yield curr_key, val
319 322 curr_key = pred_key
320 323
321 324 def ritems(self):
322 325 """List of the (key, value) in reversed order.
323 326 """
324 327 return list(self.riteritems())
325 328
326 329 def firstkey(self):
327 330 if self:
328 331 return self._dict_impl().__getattribute__(self, 'lh')
329 332 else:
330 333 raise KeyError("'firstkey(): ordered dictionary is empty'")
331 334
332 335 def lastkey(self):
333 336 if self:
334 337 return self._dict_impl().__getattribute__(self, 'lt')
335 338 else:
336 339 raise KeyError("'lastkey(): ordered dictionary is empty'")
337 340
338 341 def as_dict(self):
339 342 return self._dict_impl()(self.items())
340 343
341 344 def _repr(self):
342 345 """_repr(): low level repr of the whole data contained in the odict.
343 346 Useful for debugging.
344 347 """
345 348 dict_impl = self._dict_impl()
346 349 form = "odict low level repr lh,lt,data: %r, %r, %s"
347 350 return form % (dict_impl.__getattribute__(self, 'lh'),
348 351 dict_impl.__getattribute__(self, 'lt'),
349 352 dict_impl.__repr__(self))
350 353
351 354 class OrderedDict(_odict, dict):
352 355
353 356 def _dict_impl(self):
354 357 return dict
355 358
356 359
357 360 #==============================================================================
358 361 # OrderedSet
359 362 #==============================================================================
360 363 from sqlalchemy.util import OrderedSet
364
365
366 #==============================================================================
367 # kill FUNCTIONS
368 #==============================================================================
369 if __platform__ in PLATFORM_WIN:
370 import ctypes
371
372 def kill(pid, sig):
373 """kill function for Win32"""
374 kernel32 = ctypes.windll.kernel32
375 handle = kernel32.OpenProcess(1, 0, pid)
376 return (0 != kernel32.TerminateProcess(handle, 0))
377
378 else:
379 kill = os.kill
@@ -1,142 +1,129 b''
1 1 import os
2 2 import sys
3 3 import time
4 4 import errno
5 5
6 6 from warnings import warn
7 7 from multiprocessing.util import Finalize
8 8
9 from rhodecode import __platform__, PLATFORM_WIN
10
11 if __platform__ in PLATFORM_WIN:
12 import ctypes
13
14 def kill(pid, sig):
15 """kill function for Win32"""
16 kernel32 = ctypes.windll.kernel32
17 handle = kernel32.OpenProcess(1, 0, pid)
18 return (0 != kernel32.TerminateProcess(handle, 0))
19
20 else:
21 kill = os.kill
22
9 from rhodecode.lib.compat import kill
23 10
24 11 class LockHeld(Exception):
25 12 pass
26 13
27 14
28 15 class DaemonLock(object):
29 16 """daemon locking
30 17 USAGE:
31 18 try:
32 19 l = DaemonLock(file_='/path/tolockfile',desc='test lock')
33 20 main()
34 21 l.release()
35 22 except LockHeld:
36 23 sys.exit(1)
37 24 """
38 25
39 26 def __init__(self, file_=None, callbackfn=None,
40 27 desc='daemon lock', debug=False):
41 28
42 29 self.pidfile = file_ if file_ else os.path.join(
43 30 os.path.dirname(__file__),
44 31 'running.lock')
45 32 self.callbackfn = callbackfn
46 33 self.desc = desc
47 34 self.debug = debug
48 35 self.held = False
49 36 #run the lock automatically !
50 37 self.lock()
51 38 self._finalize = Finalize(self, DaemonLock._on_finalize,
52 39 args=(self, debug), exitpriority=10)
53 40
54 41 @staticmethod
55 42 def _on_finalize(lock, debug):
56 43 if lock.held:
57 44 if debug:
58 45 print 'leck held finilazing and running lock.release()'
59 46 lock.release()
60 47
61 48 def lock(self):
62 49 """
63 50 locking function, if lock is present it
64 51 will raise LockHeld exception
65 52 """
66 53 lockname = '%s' % (os.getpid())
67 54 if self.debug:
68 55 print 'running lock'
69 56 self.trylock()
70 57 self.makelock(lockname, self.pidfile)
71 58 return True
72 59
73 60 def trylock(self):
74 61 running_pid = False
75 62 if self.debug:
76 63 print 'checking for already running process'
77 64 try:
78 65 pidfile = open(self.pidfile, "r")
79 66 pidfile.seek(0)
80 67 running_pid = int(pidfile.readline())
81 68
82 69 pidfile.close()
83 70
84 71 if self.debug:
85 72 print ('lock file present running_pid: %s, '
86 73 'checking for execution') % running_pid
87 74 # Now we check the PID from lock file matches to the current
88 75 # process PID
89 76 if running_pid:
90 77 try:
91 78 kill(running_pid, 0)
92 79 except OSError, exc:
93 80 if exc.errno in (errno.ESRCH, errno.EPERM):
94 81 print ("Lock File is there but"
95 82 " the program is not running")
96 83 print "Removing lock file for the: %s" % running_pid
97 84 self.release()
98 85 else:
99 86 raise
100 87 else:
101 88 print "You already have an instance of the program running"
102 89 print "It is running as process %s" % running_pid
103 90 raise LockHeld()
104 91
105 92 except IOError, e:
106 93 if e.errno != 2:
107 94 raise
108 95
109 96 def release(self):
110 97 """releases the pid by removing the pidfile
111 98 """
112 99 if self.debug:
113 100 print 'trying to release the pidlock'
114 101
115 102 if self.callbackfn:
116 103 #execute callback function on release
117 104 if self.debug:
118 105 print 'executing callback function %s' % self.callbackfn
119 106 self.callbackfn()
120 107 try:
121 108 if self.debug:
122 109 print 'removing pidfile %s' % self.pidfile
123 110 os.remove(self.pidfile)
124 111 self.held = False
125 112 except OSError, e:
126 113 if self.debug:
127 114 print 'removing pidfile failed %s' % e
128 115 pass
129 116
130 117 def makelock(self, lockname, pidfile):
131 118 """
132 119 this function will make an actual lock
133 120
134 121 :param lockname: acctual pid of file
135 122 :param pidfile: the file to write the pid in
136 123 """
137 124 if self.debug:
138 125 print 'creating a file %s and pid: %s' % (pidfile, lockname)
139 126 pidfile = open(self.pidfile, "wb")
140 127 pidfile.write(lockname)
141 128 pidfile.close
142 129 self.held = True
General Comments 0
You need to be logged in to leave comments. Login now