app/django/core/files/locks.py
author Sverre Rabbelier <srabbelier@gmail.com>
Sun, 02 Nov 2008 22:50:22 +0000 (2008-11-02)
changeset 432 1851d67a1004
parent 323 ff1a9aa48cfd
permissions -rw-r--r--
Add a generic method for getting a Keyname This patch will make logic/key_name.py obsolete in the future when everything is compliant with base.logic. This also makes the naming of already compliant logic modules generic and also fixes the _name field to be consistent with the naming in key_name.py. Note: This does not use Group/Sponsor, Group/School, Group/Organisation or Group/Club. Patch by: "Lennard de Rijk" <rijk0214@gmail.com> Reviewed by: Sverre Rabbelier
"""
Portable file locking utilities.

Based partially on example by Jonathan Feignberg <jdf@pobox.com> in the Python
Cookbook, licensed under the Python Software License.

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65203

Example Usage::

    >>> from django.core.files import locks
    >>> f = open('./file', 'wb')
    >>> locks.lock(f, locks.LOCK_EX)
    >>> f.write('Django')
    >>> f.close()
"""

__all__ = ('LOCK_EX','LOCK_SH','LOCK_NB','lock','unlock')

system_type = None

try:
    import win32con
    import win32file
    import pywintypes
    LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
    LOCK_SH = 0
    LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
    __overlapped = pywintypes.OVERLAPPED()
    system_type = 'nt'
except (ImportError, AttributeError):
    pass

try:
    import fcntl
    LOCK_EX = fcntl.LOCK_EX
    LOCK_SH = fcntl.LOCK_SH
    LOCK_NB = fcntl.LOCK_NB
    system_type = 'posix'
except (ImportError, AttributeError):
    pass

def fd(f):
    """Get a filedescriptor from something which could be a file or an fd."""
    return hasattr(f, 'fileno') and f.fileno() or f

if system_type == 'nt':
    def lock(file, flags):
        hfile = win32file._get_osfhandle(fd(file))
        win32file.LockFileEx(hfile, flags, 0, -0x10000, __overlapped)

    def unlock(file):
        hfile = win32file._get_osfhandle(fd(file))
        win32file.UnlockFileEx(hfile, 0, -0x10000, __overlapped)
elif system_type == 'posix':
    def lock(file, flags):
        fcntl.lockf(fd(file), flags)

    def unlock(file):
        fcntl.lockf(fd(file), fcntl.LOCK_UN)
else:
    # File locking is not supported.
    LOCK_EX = LOCK_SH = LOCK_NB = None

    # Dummy functions that don't do anything.
    def lock(file, flags):
        pass

    def unlock(file):
        pass