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