1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
#
# This module was written in 2007 by S James S Stapleton
# This module is released as PUBLIC DOMAIN
#
# Please respect the creator/author's intent and release all
# modifications as public domain. Thank you.
#
from time import time
from time import sleep
import inheritable
class SlockG(object):
"""
This is an object returned from a Slock object on Saquire() and passed to Srelease. When this object is destroyed, is passed to
an Slock's Srelease or has it's own release() called, it will release the lock.
This object is greedy. That means it doesn't play nice and put itself to sleep while waiting for a lock. It's fast, but it will
take resources away from other things that can use them.
lock_callback, unlock_callback and cbd are for debugging. lock_callback and unlock_callback can be assigned functions, these are
called when acquire (only on a successful acquire and __del__ (only if the lock wasn't released) are called specifically. They
take three parameters, this object, the lock object and cbd. These can be used for debugging and logging to find program errors.
"""
__lock = None
__locked = None
lock_callback = None
unlock_callback = None
cbd = None
def __init__(self, lock):
"""
Initialize, but do not lock.
"""
self.__lock = lock
self.__locked = False
#def __init__(self, lock):
def __del__(self):
"""
Unlock if locked at destructor call
"""
if(self.__locked):
if(self.unlock_callback):
self.unlock_callback(self, self.__lock, cbd)
self.__lock.release()
#if(self.__locked()):
#def __destroy__(self):
def acquire(self, timeout=True):
"""
Acquire the lock held:
timeout values:
False - do not block, return false on fail, true on success
True - block indefinetly, return true
Integer/Float - wait timout seconds before failing, return false on fail, true on success.
"""
if(type(timeout) == int or
type(timeout) == float):
stop = time() + timeout
while(stop-time() > 0):
if(self.__lock.acquire(False)):
self.__locked = True
if(self.lock_callback):
self.lock_callback(self, self.__lock, cbd)
return True
#while(stop-time() > 0):
return False
self.__locked = self.acquire(timeout)
if(self.__locked and self.lock_callback):
self.lock_callback(self, self.__lock, cbd)
return self.__locked
#if(type(timeout) == int)
#def acquire(self, timeout):
def release(self):
"""
A straight duplicate of Lock's release function.
"""
self.__locked = False
self.lock.release()
#def release(self):
def unlock(self, lock):
"""
turns of the __locked variable if lock = self.__lock
"""
if(lock == self.lock):
self.__locked = False
self.__lock = None
#def unlock(self, lock):
#class SlockO(object):
class SlockE(SlockG):
"""
A non-greedy form of SlockG, it has a few more calculations when it grabs a lock, but it also will sleep when not grabbing a lock,
rather than spinning around like an out-of-control CPU hogging gorilla.
minchecks are the minimum number of times a thread will check for a lock, if timeout/sleeptime is less than minchecks, then
sleeptime is set to timeout/minchecks
"""
__minchecks = None
__sleeptime = None
def __init__(self, lock, minchecks=5, sleeptime=0.10):
"""
Initialize, but do not lock.
"""
self.__lock = lock
self.__locked = False
self.__minchecks = minchecks
self.__sleeptime = sleeptime
#def __init__(self, lock):
def acquire(self, timeout=True):
"""
Acquire the lock held:
timeout values:
False - do not block, return false on fail, true on success
True - block indefinetly, return true
Integer/Float - wait timout seconds before failing, return false on fail, true on success.
"""
if(type(timeout) == int):
timeout = float(timeout)
if(type(timeout) == float):
stop = time() + timeout
sleeptime = self.__sleeptime
#now get the sleep time, remember calcs take time too, and we would normally miss
#at least one minimum check, so we add one.
if(sleeptime < timeout/(self.__minchecks+1)):
sleeptime = timeout/(self.__minchecks+1)
while(stop-time() > 0):
if(self.__lock.acquire(False)):
self.__locked = True
if(self.lock_callback):
self.lock_callback(self, self.__lock, cbd)
return True
sleep(sleeptime)
#while(stop-time() > 0):
return False
self.__locked = self.acquire(timeout)
if(self.__locked and self.lock_callback):
self.lock_callback(self, self.__lock, cbd)
return self.__locked
#if(type(timeout) == int)
#def acquire(self, timeout):
#class SlockE(SlockG):
|