3 Pf$ @ s d Z ddlmZ ddlZddlZddlZddlZddlZeedsJej e_ eejdsbejjej_ dddd d ddd dddddg ZG dd deZG dd deZG dd deZG dd d eZG dd d eZG dd deZG dd deZG dd d eZG dd deZG dd deZdd Zd d Zd!d Zd"d Zd(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 LockErrorLockTimeout AlreadyLocked LockFailedUnlockError NotLocked NotMyLockLinkFileLock MkdirFileLockSQLiteFileLockLockBaselockedc @ s e Zd ZdZdS )r zw Base class for other exceptions. >>> try: ... raise Error ... except Exception: ... pass N)__name__ __module____qualname____doc__ r r /usr/lib/python3.6/__init__.pyr J s c @ s e Zd ZdZdS )r z Base class for error arising from attempts to acquire the lock. >>> try: ... raise LockError ... except Error: ... pass N)r r r r r r r r r V s c @ s e Zd ZdZdS )r zRaised when lock creation fails within a user-defined period of time. >>> try: ... raise LockTimeout ... except LockError: ... pass N)r r r r r r r r r b s c @ s e Zd ZdZdS )r zSome other thread/process is locking the file. >>> try: ... raise AlreadyLocked ... except LockError: ... pass N)r r r r r r r r r m s c @ s e Zd ZdZdS )r zLock file creation failed for some other reason. >>> try: ... raise LockFailed ... except LockError: ... pass N)r r r r r r r r r x s c @ s e Zd ZdZdS )r z Base class for errors arising from attempts to release the lock. >>> try: ... raise UnlockError ... except Error: ... pass N)r r r r r r r r r s c @ s e Zd ZdZdS )r zRaised when an attempt is made to unlock an unlocked file. >>> try: ... raise NotLocked ... except UnlockError: ... pass N)r r r r r r r r r s c @ s e Zd ZdZdS )r zRaised when an attempt is made to unlock a file someone else locked. >>> try: ... raise NotMyLock ... except UnlockError: ... pass N)r r r r r r r r r s c @ s> e Zd Zdd ZdddZdd Zdd Zd d Zdd ZdS )_SharedBasec C s || _ d S )N)path)selfr r r r __init__ s z_SharedBase.__init__Nc C s t ddS )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. zimplement in subclassN)NotImplemented)r timeoutr r r acquire s z_SharedBase.acquirec C s t ddS )zX Release the lock. If the file is not locked, raise NotLocked. zimplement in subclassN)r )r r r r release s z_SharedBase.releasec C s | j | S )z* Context manager support. )r )r r r r __enter__ s z_SharedBase.__enter__c G s | j dS )z* Context manager support. N)r )r Z_excr r r __exit__ s z_SharedBase.__exit__c C s d| j j| jf S )Nz<%s: %r>) __class__r r )r r r r __repr__ s z_SharedBase.__repr__)N) r r r r r r r r! r# r r r r r s r c sB e Zd ZdZd fdd Zdd Zdd Zd d Zdd Z Z S )r z.Base class for platform-specific lock classes.TNc s t t| j| tjj|d | _tj | _ tj | _|rbtj }t|dt|}d|d@ | _nd| _tjj| j}tjj|d| j | j| jt| jf | _|| _dS )zi >>> lock = LockBase('somefile') >>> lock = LockBase('somefile', threaded=False) z.lockidentz-%xl z %s%s.%s%sN)superr r osr abspathZ lock_filesocketZgethostnameZhostnamegetpidpid threadingr getattrhashZtnamedirnamejoinunique_namer )r r threadedr tr$ r/ )r" r r r s zLockBase.__init__c C s t ddS )z9 Tell whether or not the file is locked. zimplement in subclassN)r )r r r r is_locked s zLockBase.is_lockedc C s t ddS )zA Return True if this object is locking the file. zimplement in subclassN)r )r r r r i_am_locking s zLockBase.i_am_lockingc C s t ddS )zN Remove a lock. Useful if a locking thread failed to unlock. zimplement in subclassN)r )r r r r break_lock s zLockBase.break_lockc C s d| j j| j| jf S )Nz<%s: %r -- %r>)r" r r1 r )r r r r r# s zLockBase.__repr__)TN) r r r r r r4 r5 r6 r# __classcell__r r )r" r r s !c O sR t jd| tdd t|d ts.|dd }t|dkrH| rHd|d<