aboutsummaryrefslogtreecommitdiff
path: root/py11
diff options
context:
space:
mode:
Diffstat (limited to 'py11')
-rw-r--r--py11/mutex.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/py11/mutex.py b/py11/mutex.py
new file mode 100644
index 0000000..5ad30ba
--- /dev/null
+++ b/py11/mutex.py
@@ -0,0 +1,63 @@
+# Optional mutex implementation.
+
+from struct import pack, unpack
+
+# This controls how big our mutex handles are.
+encoded_format = "=L"
+
+# These are all determined by encoded_format, don't touch.
+
+encoded_length = len(pack(encoded_format, 0))
+encoded_type = CK_BYTE * encoded_length
+handle_max = unpack(encoded_format, chr(0xff) * encoded_length)[0]
+
+class Mutex(object):
+
+ def __init__(self, handle):
+ from threading import Lock
+ self.encoded = encoded_type(*handle)
+ self.lock = Lock()
+
+def p11_callback(func):
+ from threading import ThreadError
+ def wrapper(self, arg):
+ try:
+ func(self, arg)
+ except ThreadError:
+ return CKR_MUTEX_NOT_LOCKED
+ except:
+ return CKR_FUNCTION_FAILED
+ else:
+ return CKR_OK
+ return wrapper
+
+class MutexDB(object):
+
+ def __init__(self):
+ self.mutexes = {}
+ self.next_handle = 0
+
+ def find_free_handle(self):
+ if len(self.mutexes) > handle_max:
+ raise RuntimeError
+ while self.next_handle in self.mutexes:
+ self.next_handle = (self.next_handle + 1) & handle_max
+ return pack(encoded_format, self.next_handle)
+
+ @p11_callback
+ def create(self, handle_ptr):
+ handle = self.find_free_handle()
+ self.mutexes[handle] = self.mutex_type(handle)
+ handle_ptr[0] = self.mutexes[handle].encoded
+
+ @p11_callback
+ def destroy(self, handle):
+ del self.mutexes[handle[:encoded_length]]
+
+ @p11_callback
+ def lock(self, handle):
+ self.mutexes[handle[:encoded_length]].lock.acquire()
+
+ @p11_callback
+ def unlock(self, handle):
+ self.mutexes[handle[:encoded_length]].lock.release()