diff options
author | Rob Austein <sra@hactrn.net> | 2015-09-20 15:01:25 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2015-09-20 15:01:25 -0400 |
commit | fc79084886aa81e7414a4bd2aba48aa96a0b641b (patch) | |
tree | ae9a4a4a991facef564693250fb828c05ddfe581 /py11 | |
parent | ec3be7d441b7bc1888186c05db6e6b46abe63879 (diff) |
Implement mutexes in py11 library using threading.Lock objects.
Diffstat (limited to 'py11')
-rw-r--r-- | py11/mutex.py | 63 |
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() |