B
     9-e&              	   @   s  d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddl	Z	G dd deZ
edkrddlZddlZddlZddlZe Zejed	Zed
e e
eZdddZejeeddZejeeddZejeeddZejeeddZe  e  e  e  e  e  e  e  ejej r`t!de"edZ#ej$%e#&  W dQ R X dS )a  
Implementation of a simple cross-platform file locking mechanism.
This is a modified version of code retrieved on 2013-01-01 from
http://www.evanfosmark.com/2009/01/cross-platform-file-locking-support-in-python.
(The original code was released under the BSD License.  See below for details.)
Modifications in this version:
 - Tweak docstrings for sphinx.
 - Accept an absolute path for the protected file (instead of a file name relative to cwd).
 - Allow timeout to be None.
 - Fixed a bug that caused the original code to be NON-threadsafe when the same FileLock instance was shared by multiple threads in one process.
   (The original was safe for multiple processes, but not multiple threads in a single process.  This version is safe for both cases.)
 - Added ``purge()`` function.
 - Added ``available()`` function.
 - Expanded API to mimic ``threading.Lock interface``:
   - ``__enter__`` always calls ``acquire()``, and therefore blocks if ``acquire()`` was called previously.
   - ``__exit__`` always calls ``release()``.  It is therefore a bug to call ``release()`` from within a context manager.
   - Added ``locked()`` function.
   - Added blocking parameter to ``acquire()`` method
WARNINGS:
 - The locking mechanism used here may need to be changed to support old NFS filesystems:
   http://lwn.net/Articles/251004
   (Newer versions of NFS should be okay, e.g. NFSv3 with Linux kernel 2.6. Check the open(2) man page for details about O_EXCL.)
 - This code has not been thoroughly tested on Windows, and there has been one report of incorrect results on Windows XP and Windows 7.
   The locking mechanism used in this class should (in theory) be cross-platform, but use at your own risk.
ORIGINAL LICENSE:
The original code did not properly include license text.
(It merely said "License: BSD".)
Therefore, we'll attach the following generic BSD License terms to this file.
Those who extract this file from the lazyflow code base (LGPL) for their own use
are therefore bound by the terms of both the Simplified BSD License below AND the LGPL.
Copyright (c) 2013, Evan Fosmark and others.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
    )print_function)range)objectNc               @   sl   e Zd ZdZG dd deZdddZdd	 Zd
d ZdddZ	dd Z
dd Zdd Zdd Zdd ZdS )FileLockz A file locking mechanism that has context-manager support so
        you can use it in a ``with`` statement. This should be relatively cross
        compatible as it doesn't rely on ``msvcrt`` or ``fcntl`` for the locking.
    c               @   s   e Zd ZdS )zFileLock.FileLockExceptionN)__name__
__module____qualname__ r	   r	   G:\My Drive\STUDY\EPAT\09 TBP - Trading & Back-testing Platforms\TBP04 - Backtesting & Live Trading\IB IBridgePy API\02 Python 3.7 IBridgePy_Win_Anaconda37_64\BasicPyLib\fileLock.pyFileLockException[   s   r   N   c             C   sX   d| _ |d | _|| _|| _|| _| jdkrTd| _x tjD ]}|  j|d 7  _q:W dS )z Prepare the file locker. Specify the file to lock and optionally
            the maximum timeout and the delay between each attempt to lock.
        Fz.lockNzOwning process args:

)	is_lockedlockfiletimeoutdelay_lock_file_contentssysargv)selfZprotected_file_pathr   r   Zlock_file_contentsargr	   r	   r
   __init__^   s    

zFileLock.__init__c             C   s   | j S )z
        Returns True iff the file is owned by THIS FileLock instance.
        (Even if this returns false, the file could be owned by another FileLock instance, possibly in a different thread or process).
        )r   )r   r	   r	   r
   lockedl   s    zFileLock.lockedc             C   s   t j| j S )zP
        Returns True iff the file is currently available to be locked.
        )ospathexistsr   )r   r	   r	   r
   	availables   s    zFileLock.availableTc          
   C   s   t   }xyFt| jtjtjB tjB }t|d}|| j	 W dQ R X P W q
 t
k
r } zL|jtjkrp | jdk	rt   | | jkrtd|sdS t | j W dd}~X Y q
X q
W d| _dS )a   Acquire the lock, if possible. If the lock is in use, and `blocking` is False, return False.
            Otherwise, check again every `self.delay` seconds until it either gets the lock or
            exceeds `timeout` number of seconds, in which case it raises an exception.
        aNzTimeout occurred.FT)timer   openr   O_CREATO_EXCLO_RDWRfdopenwriter   OSErrorerrnoEEXISTr   r   r   sleepr   r   )r   blocking
start_timefdfer	   r	   r
   acquirey   s"    
"zFileLock.acquirec             C   s   d| _ t| j dS )z Get rid of the lock by deleting the lockfile.
            When working in a `with` statement, this gets automatically
            called at the end.
        FN)r   r   unlinkr   )r   r	   r	   r
   release   s    zFileLock.releasec             C   s   |    | S )z Activated when used in the with statement.
            Should automatically acquire a lock to be used in the with block.
        )r.   )r   r	   r	   r
   	__enter__   s    zFileLock.__enter__c             C   s   |    dS )zx Activated at the end of the with statement.
            It automatically releases the lock if it isn't locked.
        N)r0   )r   typevalue	tracebackr	   r	   r
   __exit__   s    zFileLock.__exit__c             C   s   | j r|   dS )zc Make sure this ``FileLock`` instance doesn't leave a .lock file
            lying around.
        N)r   r0   )r   r	   r	   r
   __del__   s    zFileLock.__del__c             C   s   t j| jr|   dS dS )zU
        For debug purposes only.  Removes the lock file from the hard disk.
        TF)r   r   r   r   r0   )r   r	   r	   r
   purge   s    zFileLock.purge)Nr   N)T)r   r   r   __doc__	Exceptionr   r   r   r   r.   r0   r1   r5   r6   r7   r	   r	   r	   r
   r   U   s   

r   __main__zsomefile.txtzProtecting file: {}
   c             C   sR   t D x<t|D ]0}ttd}|| d  |  W d Q R X qW W d Q R X d S )Nr   r   )flr   r   protected_filepathr$   flush)linerepeat_r,   r	   r	   r
   
writeLines   s
    rB   Z1111111111111111111111111111111)targetZ2222222222222222222222222222222Z3333333333333333333333333333333Z4444444444444444444444444444444z The lock file wasn't cleaned up!r)r;   )'r8   
__future__r   builtinsr   r   r   r   r   r&   r   r   	functools	threadingtempfilemkdtemptemp_dirr   joinr=   printformatr<   rB   ThreadpartialZth1Zth2Zth3Zth4startr   r   AssertionErrorr   r,   stdoutr$   readr	   r	   r	   r
   <module>J   sB   d

