U UV$ @sdZddlmZddlZddlZddlZddlZddlZeedsJej e_ eej dsbej j ej _ dddd d d d d dddddg ZGdddeZGdddeZGdddeZGdd d eZGdd d eZGdd d eZGdd d eZGdd d eZGdddeZGdddeZddZd dZd!dZd"dZd(d#dZeed$rjd%d&l m!Z"e"j#Z$nd%d'l m%Z&e&j'Z$e$Z(dS))a lockfile.py - Platform-independent advisory file locks. Requires Python 2.5 unless you apply 2.4.diff Locking is done on a per-thread basis instead of a per-process basis. Usage: >>> lock = LockFile('somefile') >>> try: ... lock.acquire() ... except AlreadyLocked: ... print 'somefile', 'is locked already.' ... except LockFailed: ... print 'somefile', 'can\'t be locked.' ... else: ... print 'got lock' got lock >>> print lock.is_locked() True >>> lock.release() >>> lock = LockFile('somefile') >>> print lock.is_locked() False >>> with lock: ... print lock.is_locked() True >>> print lock.is_locked() False >>> lock = LockFile('somefile') >>> # It is okay to lock twice from the same thread... >>> with lock: ... lock.acquire() ... >>> # Though no counter is kept, so you can't unlock multiple times... >>> print lock.is_locked() False Exceptions: Error - base class for other exceptions LockError - base class for all locking exceptions AlreadyLocked - Another thread or process already holds the lock LockFailed - Lock failed for some other reason UnlockError - base class for all unlocking exceptions AlreadyUnlocked - File was not locked. NotMyLock - File was locked but not by the current thread/process )absolute_importNcurrent_threadget_nameError LockError LockTimeout AlreadyLocked LockFailed UnlockError NotLocked NotMyLock LinkFileLock MkdirFileLockSQLiteFileLockLockBaselockedc@seZdZdZdS)rzw Base class for other exceptions. >>> try: ... raise Error ... except Exception: ... pass N__name__ __module__ __qualname____doc__rr /__init__.pyrJsc@seZdZdZdS)rz Base class for error arising from attempts to acquire the lock. >>> try: ... raise LockError ... except Error: ... pass NrrrrrrVsc@seZdZdZdS)rzRaised when lock creation fails within a user-defined period of time. >>> try: ... raise LockTimeout ... except LockError: ... pass Nrrrrrrbsc@seZdZdZdS)rzSome other thread/process is locking the file. >>> try: ... raise AlreadyLocked ... except LockError: ... pass Nrrrrrrmsc@seZdZdZdS)r zLock file creation failed for some other reason. >>> try: ... raise LockFailed ... except LockError: ... pass Nrrrrrr xsc@seZdZdZdS)r z Base class for errors arising from attempts to release the lock. >>> try: ... raise UnlockError ... except Error: ... pass Nrrrrrr sc@seZdZdZdS)r zRaised when an attempt is made to unlock an unlocked file. >>> try: ... raise NotLocked ... except UnlockError: ... pass Nrrrrrr sc@seZdZdZdS)r zRaised when an attempt is made to unlock a file someone else locked. >>> try: ... raise NotMyLock ... except UnlockError: ... pass Nrrrrrr sc@s>eZdZddZdddZddZdd Zd d Zd d ZdS) _SharedBasecCs ||_dS)N)path)selfrrrr__init__sz_SharedBase.__init__NcCs tddS)a Acquire the lock. * If timeout is omitted (or None), wait forever trying to lock the file. * If timeout > 0, try to acquire the lock for that many seconds. If the lock period expires and the file is still locked, raise LockTimeout. * If timeout <= 0, raise AlreadyLocked immediately if the file is already locked. implement in subclassNNotImplemented)rtimeoutrrracquiresz_SharedBase.acquirecCs tddS)zX Release the lock. If the file is not locked, raise NotLocked. rNrrrrrreleasesz_SharedBase.releasecCs ||S)* Context manager support. )r!r"rrr __enter__sz_SharedBase.__enter__cGs |dS)r$N)r#)rZ_excrrr__exit__sz_SharedBase.__exit__cCsd|jj|jfS)Nz<%s: %r>) __class__rrr"rrr__repr__sz_SharedBase.__repr__)N) rrrrr!r#r%r&r(rrrrrs  rcsBeZdZdZdfdd ZddZdd Zd d Zd d ZZ S)rz.Base class for platform-specific lock classes.TNc stt||tj|d|_t|_ t |_ |rbt }t|dt|}d|d@|_nd|_tj|j}tj|d|j |j|j t|jf|_||_dS)zi >>> lock = LockBase('somefile') >>> lock = LockBase('somefile', threaded=False) z.lockidentz-%xlz %s%s.%s%sN)superrrosrabspathZ lock_filesocketZ gethostnameZhostnamegetpidpid threadingrgetattrhashZtnamedirnamejoin unique_namer )rrthreadedr tr)r4r'rrrs$   zLockBase.__init__cCs tddS)z9 Tell whether or not the file is locked. rNrr"rrr is_lockedszLockBase.is_lockedcCs tddS)zA Return True if this object is locking the file. rNrr"rrr i_am_lockingszLockBase.i_am_lockingcCs tddS)zN Remove a lock. Useful if a locking thread failed to unlock. rNrr"rrr break_lockszLockBase.break_lockcCsd|jj|j|jfS)Nz<%s: %r -- %r>)r'rr6rr"rrrr(s zLockBase.__repr__)TN) rrrrrr:r;r<r( __classcell__rrr9rrs !cOsPtjd|tddt|dts.|dd}t|dkrF|sFd|d<|||S)Nz1Import from %s module instead of lockfile package) stacklevelrTr7)warningswarnDeprecationWarning isinstancestrlen)clsmodargskwdsrrr _fl_helper s  rKcOs ddlm}t|jdf||S)zFactory function provided for backwards compatibility. Do not use in new code. Instead, import LinkLockFile from the lockfile.linklockfile module. r@ linklockfilezlockfile.linklockfile)r*rMrK LinkLockFile)rIrJrMrrrr s   cOs ddlm}t|jdf||S)zFactory function provided for backwards compatibility. Do not use in new code. Instead, import MkdirLockFile from the lockfile.mkdirlockfile module. r@ mkdirlockfilezlockfile.mkdirlockfile)r*rPrK MkdirLockFile)rIrJrPrrrr%s   cOs ddlm}t|jdf||S)zFactory function provided for backwards compatibility. Do not use in new code. Instead, import SQLiteLockFile from the lockfile.mkdirlockfile module. r@)sqlitelockfilezlockfile.sqlitelockfile)r*rRrKZSQLiteLockFile)rIrJrRrrrr0s   csfdd}|S)aDecorator which enables locks for decorated function. Arguments: - path: path for lockfile. - timeout (optional): Timeout for acquiring lock. Usage: @locked('/var/run/myname', timeout=0) def myname(...): ... cstfdd}|S)Ncs2td}|z||WS|XdS)N)r )FileLockr!r#)rIkwargslock)funcrr rrwrapperHs  z&locked..decor..wrapper) functoolswraps)rVrWrr )rVrdecorGszlocked..decorr)rr r[rrZrr;s  linkr@rLrO)N))rZ __future__rrXr,r.r1rAhasattrZ currentThreadrZThreadZgetNamer__all__ Exceptionrrrrr r r r objectrrrKr rrrr*rMZ_llfrNZLockFilerPZ_mlfrQrSrrrrsT3            -: