???<!-- GIF89;a -->
123123123123
.....................................................................................................................................???<!-- GIF89;a -->
123123123123
.....................................................................................................................................ó
¿œ^c           @   sô   d  Z  d d l Z d d l Z d d l Z d d l Z d Z d Z d Z d Z d Z	 d d d	 „  ƒ  YZ
 d
 e
 f d „  ƒ  YZ d d d „  ƒ  YZ d „  Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ e d „ Z d „  Z e d k rð e ƒ  n  d S(   sû  CVS locking algorithm.

CVS locking strategy
====================

As reverse engineered from the CVS 1.3 sources (file lock.c):

- Locking is done on a per repository basis (but a process can hold
write locks for multiple directories); all lock files are placed in
the repository and have names beginning with "#cvs.".

- Before even attempting to lock, a file "#cvs.tfl.<pid>" is created
(and removed again), to test that we can write the repository.  [The
algorithm can still be fooled (1) if the repository's mode is changed
while attempting to lock; (2) if this file exists and is writable but
the directory is not.]

- While creating the actual read/write lock files (which may exist for
a long time), a "meta-lock" is held.  The meta-lock is a directory
named "#cvs.lock" in the repository.  The meta-lock is also held while
a write lock is held.

- To set a read lock:

        - acquire the meta-lock
        - create the file "#cvs.rfl.<pid>"
        - release the meta-lock

- To set a write lock:

        - acquire the meta-lock
        - check that there are no files called "#cvs.rfl.*"
                - if there are, release the meta-lock, sleep, try again
        - create the file "#cvs.wfl.<pid>"

- To release a write lock:

        - remove the file "#cvs.wfl.<pid>"
        - rmdir the meta-lock

- To release a read lock:

        - remove the file "#cvs.rfl.<pid>"


Additional notes
----------------

- A process should read-lock at most one repository at a time.

- A process may write-lock as many repositories as it wishes (to avoid
deadlocks, I presume it should always lock them top-down in the
directory hierarchy).

- A process should make sure it removes all its lock files and
directories when it crashes.

- Limitation: one user id should not be committing files into the same
repository at the same time.


Turn this into Python code
--------------------------

rl = ReadLock(repository, waittime)

wl = WriteLock(repository, waittime)

list = MultipleWriteLock([repository1, repository2, ...], waittime)

iÿÿÿÿNi
   i   s   #cvs.lcks	   #cvs.rfl.s	   #cvs.wfl.t   Errorc           B   s#   e  Z d  „  Z d „  Z d „  Z RS(   c         C   s   | |  _  d  S(   N(   t   msg(   t   selfR   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyt   __init__`   s    c         C   s   t  |  j ƒ S(   N(   t   reprR   (   R   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyt   __repr__c   s    c         C   s   t  |  j ƒ S(   N(   t   strR   (   R   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyt   __str__f   s    (   t   __name__t
   __module__R   R   R   (    (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR    ^   s   		t   Lockedc           B   s   e  Z RS(    (   R   R	   (    (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR
   j   s   t   Lockc           B   sV   e  Z d  e d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 RS(	   t   .c         C   sx   | |  _  | |  _ d  |  _ d  |  _ t t j ƒ  ƒ } |  j t	 ƒ |  _
 |  j t | ƒ |  _ |  j t | ƒ |  _ d  S(   N(   t
   repositoryt   delayt   Nonet   lockdirt   lockfileR   t   ost   getpidt   joint   CVSLCKt   cvslckt   CVSRFLt   cvsrflt   CVSWFLt   cvswfl(   R   R   R   t   pid(    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR   p   s    				c         C   s   d GH|  j  ƒ  d  S(   Nt   __del__(   t   unlock(   R   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR   z   s    c         C   sÀ   x¹ y' |  j  |  _ t j |  j  d ƒ d  SWq t j k
 r· } d  |  _ | d t k r› y t j |  j  ƒ } Wn t j k
 r‡ q n X|  j | ƒ q n  t	 d |  j
 | f ƒ ‚ q Xq Wd  S(   Niÿ  i    s   failed to lock %s: %s(   R   R   R   t   mkdirt   errorR   t   EEXISTt   statt   sleepR    R   (   R   R   t   st(    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyt
   setlockdir~   s     	c         C   s   |  j  ƒ  |  j ƒ  d  S(   N(   t
   unlockfilet	   unlockdir(   R   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR      s    
c         C   sP   |  j  rL d G|  j  GHy t j |  j  ƒ Wn t j k
 r? n Xd  |  _  n  d  S(   Nt   unlink(   R   R   R'   R   R   (   R   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR%   ”   s    	c         C   sP   |  j  rL d G|  j  GHy t j |  j  ƒ Wn t j k
 r? n Xd  |  _  n  d  S(   Nt   rmdir(   R   R   R(   R   R   (   R   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR&      s    	c         C   s   t  | |  j |  j ƒ d  S(   N(   R"   R   R   (   R   R#   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR"   ¦   s    c         C   s   t  j j |  j | ƒ S(   N(   R   t   pathR   R   (   R   t   name(    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR   ©   s    (   R   R	   t   DELAYR   R   R$   R   R%   R&   R"   R   (    (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR   n   s   
								c         C   sŸ   | d k r t  |  ƒ ‚ n  |  t j } y t j | ƒ } | d } Wn t k
 rb d | } n Xd t j t j ƒ  ƒ d d !Gd | G| GHt j | ƒ d  S(   Ni    s   uid %ds   [%s]i   i   s   Waiting for %s's lock in(	   R
   R!   t   ST_UIDt   pwdt   getpwuidt   KeyErrort   timet   ctimeR"   (   R#   R   R   t   uidt   pwentt   user(    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR"   ­   s    t   ReadLockc           B   s   e  Z e d  „ Z RS(   c         C   sz   t  j |  | | ƒ d } z< |  j ƒ  |  j |  _ t |  j d ƒ } | j ƒ  d } Wd  | sk |  j ƒ  n  |  j ƒ  Xd  S(   Ni    t   wi   (	   R   R   R$   R   R   t   opent   closeR%   R&   (   R   R   R   t   okt   fp(    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR   ½   s    


(   R   R	   R+   R   (    (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR5   »   s   t	   WriteLockc           B   s   e  Z e d  „ Z d „  Z RS(   c         C   s}   t  j |  | | ƒ |  j ƒ  x1 |  j ƒ  } | s6 Pn  |  j ƒ  |  j | ƒ q  W|  j |  _ t |  j d ƒ } | j	 ƒ  d  S(   NR6   (
   R   R   R$   t   readers_existR&   R"   R   R   R7   R8   (   R   R   R   R2   R:   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR   Î   s    

c         C   sw   t  t ƒ } xd t j |  j ƒ D]P } | |  t k r y t j |  j | ƒ ƒ } Wn t j k
 rj q n X| Sq Wd  S(   N(	   t   lenR   R   t   listdirR   R!   R   R   R   (   R   t   nR*   R#   (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR<   Û   s    (   R   R	   R+   R   R<   (    (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyR;   Ì   s   c         C   sj   xc g  } xC |  D]: } y | j  t | d ƒ ƒ Wq t k
 rI } ~ Pq Xq WPt | j | | ƒ q Wt S(   Ni    (   t   appendR;   R
   R"   R   t   list(   t   repositoriesR   t   lockst   rt   instance(    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyt   MultipleWriteLockç   s    	c          C   sò   d d  l  }  |  j d r) |  j d } n d } d  } d  } zD d GHt | ƒ } d GH| j ƒ  d GHt | ƒ } d GH| j ƒ  Wd  d g GHd  |  _ d g GH| r® | j ƒ  n  d g GH| rÉ | j ƒ  n  d	 g GHd  } d
 g GHd  } d g GHXd  S(   Niÿÿÿÿi   R   s   attempting write lock ...s   got it.s   attempting read lock ...i   i   i   i   i   (   t   syst   argvR   R;   R   R5   t   exc_traceback(   RG   R   t   rlt   wl(    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyt   testö   s8    
	t   __main__(    (    (   t   __doc__R   R0   R!   R-   R+   R    R   R   R   R    R
   R   R"   R5   R;   RF   RL   R   (    (    (    s*   /usr/lib64/python2.7/Demo/pdist/cvslock.pyt   <module>G   s&   ?		!