From fc79084886aa81e7414a4bd2aba48aa96a0b641b Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 20 Sep 2015 15:01:25 -0400 Subject: Implement mutexes in py11 library using threading.Lock objects. --- py11/mutex.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 py11/mutex.py (limited to 'py11') 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() -- cgit v1.2.3