blob: 5ad30ba02caf93df3f972ada2db987064fad86bb (
plain) (
tree)
|
|
# 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()
|