<s> """<STR_LIT>""" <EOL> from __future__ import division <EOL> import sys <EOL> import socket <EOL> import os <EOL> import threading <EOL> import time <EOL> import errno <EOL> from . compat import quote , get_ident <EOL> if not hasattr ( threading , "<STR_LIT>" ) : <EOL> threading . current_thread = threading . currentThread <EOL> if not hasattr ( threading . Thread , "<STR_LIT>" ) : <EOL> threading . Thread . get_name = threading . Thread . getName <EOL> __all__ = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> class Error ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class LockError ( Error ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class LockTimeout ( LockError ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class AlreadyLocked ( LockError ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class LockFailed ( LockError ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class UnlockError ( Error ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class NotLocked ( UnlockError ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class NotMyLock ( UnlockError ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> class LockBase : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , path , threaded = True ) : <EOL> """<STR_LIT>""" <EOL> self . path = path <EOL> self . lock_file = os . path . abspath ( path ) + "<STR_LIT>" <EOL> self . hostname = socket . gethostname ( ) <EOL> self . pid = os . getpid ( ) <EOL> if threaded : <EOL> name = threading . current_thread ( ) . get_name ( ) <EOL> tname = "<STR_LIT>" % quote ( name , safe = "<STR_LIT>" ) <EOL> else : <EOL> tname = "<STR_LIT>" <EOL> dirname = os . path . dirname ( self . lock_file ) <EOL> self . unique_name = os . path . join ( dirname , <EOL> "<STR_LIT>" % ( self . hostname , <EOL> tname , <EOL> self . pid ) ) <EOL> def acquire ( self , timeout = None ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def release ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def is_locked ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def i_am_locking ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def break_lock ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( "<STR_LIT>" ) <EOL> def __enter__ ( self ) : <EOL> """<STR_LIT>""" <EOL> self . acquire ( ) <EOL> return self <EOL> def __exit__ ( self , * _exc ) : <EOL> """<STR_LIT>""" <EOL> self . release ( ) <EOL> class LinkFileLock ( LockBase ) : <EOL> """<STR_LIT>""" <EOL> def acquire ( self , timeout = None ) : <EOL> try : <EOL> open ( self . unique_name , "<STR_LIT:wb>" ) . close ( ) <EOL> except IOError : <EOL> raise LockFailed ( "<STR_LIT>" % self . unique_name ) <EOL> end_time = time . time ( ) <EOL> if timeout is not None and timeout > <NUM_LIT:0> : <EOL> end_time += timeout <EOL> while True : <EOL> try : <EOL> os . link ( self . unique_name , self . lock_file ) <EOL> except OSError : <EOL> nlinks = os . stat ( self . unique_name ) . st_nlink <EOL> if nlinks == <NUM_LIT:2> : <EOL> return <EOL> else : <EOL> if timeout is not None and time . time ( ) > end_time : <EOL> os . unlink ( self . unique_name ) <EOL> if timeout > <NUM_LIT:0> : <EOL> raise LockTimeout <EOL> else : <EOL> raise AlreadyLocked <EOL> time . sleep ( timeout is not None and ( timeout / <NUM_LIT:10> ) or <NUM_LIT:0.1> ) <EOL> else : <EOL> return <EOL> def release ( self ) : <EOL> if not self . is_locked ( ) : <EOL> raise NotLocked <EOL> elif not os . path . exists ( self . unique_name ) : <EOL> raise NotMyLock <EOL> os . unlink ( self . unique_name ) <EOL> os . unlink ( self . lock_file ) <EOL> def is_locked ( self ) : <EOL> return os . path . exists ( self . lock_file ) <EOL> def i_am_locking ( self ) : <EOL> return ( self . is_locked ( ) and <EOL> os . path . exists ( self . unique_name ) and <EOL> os . stat ( self . unique_name ) . st_nlink == <NUM_LIT:2> ) <EOL> def break_lock ( self ) : <EOL> if os . path . exists ( self . lock_file ) : <EOL> os . unlink ( self . lock_file ) <EOL> class MkdirFileLock ( LockBase ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , path , threaded = True ) : <EOL> """<STR_LIT>""" <EOL> LockBase . __init__ ( self , path , threaded ) <EOL> if threaded : <EOL> tname = "<STR_LIT>" % get_ident ( ) <EOL> else : <EOL> tname = "<STR_LIT>" <EOL> self . unique_name = os . path . join ( <EOL> self . lock_file , <EOL> "<STR_LIT>" . format ( self . hostname , tname , self . pid ) <EOL> ) <EOL> def attempt_acquire ( self , timeout , end_time , wait ) : <EOL> try : <EOL> os . mkdir ( self . lock_file ) <EOL> except OSError : <EOL> err = sys . exc_info ( ) [ <NUM_LIT:1> ] <EOL> if err . errno == errno . EEXIST : <EOL> if os . path . exists ( self . unique_name ) : <EOL> return <EOL> if timeout is not None and time . time ( ) > end_time : <EOL> if timeout > <NUM_LIT:0> : <EOL> raise LockTimeout <EOL> else : <EOL> raise AlreadyLocked <EOL> time . sleep ( wait ) <EOL> else : <EOL> raise LockFailed ( "<STR_LIT>" % self . lock_file ) <EOL> else : <EOL> open ( self . unique_name , "<STR_LIT:wb>" ) . close ( ) <EOL> return <EOL> def acquire ( self , timeout = None ) : <EOL> end_time = time . time ( ) <EOL> if timeout is not None and timeout > <NUM_LIT:0> : <EOL> end_time += timeout <EOL> if timeout is None : <EOL> wait = <NUM_LIT:0.1> <EOL> else : <EOL> wait = max ( <NUM_LIT:0> , timeout / <NUM_LIT:10> ) <EOL> while True : <EOL> self . attempt_acquire ( self , timeout , end_time , wait ) <EOL> def release ( self ) : <EOL> if not self . is_locked ( ) : <EOL> raise NotLocked <EOL> elif not os . path . exists ( self . unique_name ) : <EOL> raise NotMyLock <EOL> os . unlink ( self . unique_name ) <EOL> os . rmdir ( self . lock_file ) <EOL> def is_locked ( self ) : <EOL> return os . path . exists ( self . lock_file ) <EOL> def i_am_locking ( self ) : <EOL> return ( self . is_locked ( ) and <EOL> os . path . exists ( self . unique_name ) ) <EOL> def break_lock ( self ) : <EOL> if os . path . exists ( self . lock_file ) : <EOL> for name in os . listdir ( self . lock_file ) : <EOL> os . unlink ( os . path . join ( self . lock_file , name ) ) <EOL> os . rmdir ( self . lock_file ) <EOL> class SQLiteFileLock ( LockBase ) : <EOL> """<STR_LIT>""" <EOL> import tempfile <EOL> _fd , testdb = tempfile . mkstemp ( ) <EOL> os . close ( _fd ) <EOL> os . unlink ( testdb ) <EOL> del _fd , tempfile <EOL> def __init__ ( self , path , threaded = True ) : <EOL> LockBase . __init__ ( self , path , threaded ) <EOL> self . lock_file = self . lock_file <EOL> self . unique_name = self . unique_name <EOL> import sqlite3 <EOL> self . connection = sqlite3 . connect ( SQLiteFileLock . testdb ) <EOL> cursor = self . connection . cursor ( ) <EOL> try : <EOL> cursor . execute ( "<STR_LIT>" <EOL> "<STR_LIT:(>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT:)>" ) <EOL> except sqlite3 . OperationalError : <EOL> pass <EOL> else : <EOL> self . connection . commit ( ) <EOL> import atexit <EOL> atexit . register ( os . unlink , SQLiteFileLock . testdb ) <EOL> def create_lock ( self , cursor ) : <EOL> cursor . execute ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( self . lock_file , self . unique_name ) ) <EOL> self . connection . commit ( ) <EOL> cursor . execute ( "<STR_LIT>" , <EOL> ( self . unique_name , ) ) <EOL> rows = cursor . fetchall ( ) <EOL> if len ( rows ) > <NUM_LIT:1> : <EOL> cursor . execute ( "<STR_LIT>" , <EOL> ( self . unique_name , ) ) <EOL> self . connection . commit ( ) <EOL> return False <EOL> return True <EOL> def i_am_the_only_lock ( self , cursor ) : <EOL> cursor . execute ( "<STR_LIT>" , <EOL> ( self . unique_name , ) ) <EOL> rows = cursor . fetchall ( ) <EOL> if len ( rows ) == <NUM_LIT:1> : <EOL> return <EOL> def attempt_acquire ( self , timeout , cursor , end_time , wait ) : <EOL> if self . is_locked ( ) : <EOL> if self . i_am_the_only_lock ( cursor ) : <EOL> return <EOL> else : <EOL> if self . create_lock ( cursor ) : <EOL> return <EOL> if timeout is not None and time . time ( ) > end_time : <EOL> if timeout > <NUM_LIT:0> : <EOL> raise LockTimeout <EOL> else : <EOL> raise AlreadyLocked <EOL> time . sleep ( wait ) <EOL> def acquire ( self , timeout = None ) : <EOL> end_time = time . time ( ) <EOL> if timeout is not None and timeout > <NUM_LIT:0> : <EOL> end_time += timeout <EOL> if timeout is None : <EOL> wait = <NUM_LIT:0.1> <EOL> elif timeout <= <NUM_LIT:0> : <EOL> wait = <NUM_LIT:0> <EOL> else : <EOL> wait = timeout / <NUM_LIT:10> <EOL> cursor = self . connection . cursor ( ) <EOL> while True : <EOL> self . attempt_acquire ( self , timeout , cursor , end_time , wait ) <EOL> def release ( self ) : <EOL> if not self . is_locked ( ) : <EOL> raise NotLocked <EOL> if not self . i_am_locking ( ) : <EOL> raise NotMyLock ( ( self . _who_is_locking ( ) , self . unique_name ) ) <EOL> cursor = self . connection . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( self . unique_name , ) ) <EOL> self . connection . commit ( ) <EOL> def _who_is_locking ( self ) : <EOL> cursor = self . connection . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( self . lock_file , ) ) <EOL> return cursor . fetchone ( ) [ <NUM_LIT:0> ] <EOL> def is_locked ( self ) : <EOL> cursor = self . connection . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( self . lock_file , ) ) <EOL> rows = cursor . fetchall ( ) <EOL> return not not rows <EOL> def i_am_locking ( self ) : <EOL> cursor = self . connection . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( self . lock_file , self . unique_name ) ) <EOL> return not not cursor . fetchall ( ) <EOL> def break_lock ( self ) : <EOL> cursor = self . connection . cursor ( ) <EOL> cursor . execute ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> ( self . lock_file , ) ) <EOL> self . connection . commit ( ) <EOL> if hasattr ( os , "<STR_LIT>" ) : <EOL> FileLock = LinkFileLock <EOL> else : <EOL> FileLock = MkdirFileLock </s>
