3
# Copyright (C) 2013 Canonical Ltd.
3
# Copyright (C) 2013, 2016 Canonical Ltd.
4
4
# Author: Colin Watson <cjwatson@ubuntu.com>
6
6
# This program is free software: you can redistribute it and/or modify
15
15
# You should have received a copy of the GNU General Public License
16
16
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18
"""Atomic counting semaphore files.
20
This implements two operations, namely test-increment (test non-zero,
21
increment, return state of test) and decrement-test (decrement, test
22
non-zero, return state of test), which are sufficient for use as a shared
23
lock which only opens when all users have unlocked. It is an error to call
24
decrement-test on a semaphore that is already zero.
26
The semaphore state is returned on stdout to allow the exit status to be
27
used to report errors.
18
"""PID files containing multiple PIDs.
20
This implements two operations, namely test-add (test non-empty, add PID,
21
return state of test) and remove-test (remove PID, test non-empty, return
22
state of test), which are sufficient for use as a shared lock which only
23
opens when all users have unlocked. Dead processes are automatically
24
ignored and removed. It is an error to call test-add with a PID that is
25
already in the file, or remove-test with a PID that is not already in the
28
The state is returned on stdout; a non-zero exit status indicates an error.
30
31
from __future__ import print_function
40
from cdimage.semaphore import Semaphore, SemaphoreError
41
from cdimage.multipidfile import MultiPIDFile, MultiPIDFileError
42
parser = OptionParser("%prog test-increment|decrement-test SEMAPHORE")
43
parser = OptionParser("%prog FILE test-add|remove-test PID")
43
44
_, args = parser.parse_args()
46
parser.error("need file name")
45
48
parser.error("need operation")
47
parser.error("need semaphore file name")
49
semaphore = Semaphore(path)
50
parser.error("need PID")
51
path, mode, pid = args[:3]
52
multipidfile = MultiPIDFile(path)
51
if mode == "test-increment":
52
print(semaphore.test_increment())
53
elif mode == "decrement-test":
54
print(semaphore.decrement_test())
54
if mode == "test-add":
55
for pid in sorted(multipidfile.test_add(int(pid))):
57
elif mode == "remove-test":
58
for pid in sorted(multipidfile.remove_test(int(pid))):
56
parser.error("unknown semaphore operation '%s'" % mode)
57
except SemaphoreError as e:
61
parser.error("unknown multipidfile operation '%s'" % mode)
62
except MultiPIDFileError as e:
58
63
print(e, file=sys.stderr)