from threading import Lock
from fasteners.process_lock import InterProcessLock


class ComboLock():
    """ A combined process and thread lock. """
    def __init__(self, path):
        self.plock = InterProcessLock(path)
        self.tlock = Lock()

    def acquire(self, blocking=True):
        """ Acquire lock, locks thread and process lock.

        Arguments:
            blocking(bool): Set's blocking mode of acquire operation.
                            Default True.

        Returns: True if lock succeeded otherwise False
        """
        if not blocking:
            # Lock thread
            tlocked = self.tlock.acquire(blocking=False)
            if not tlocked:
                return False
            # Lock process
            plocked = self.plock.acquire(blocking=False)
            if not plocked:
                # Release thread lock if process couldn't be locked
                self.tlock.release()
                return False
        else:  # blocking, just wait and acquire ALL THE LOCKS!!!
            self.tlock.acquire()
            self.plock.acquire()
        return True

    def release(self):
        """ Release acquired lock. """
        self.plock.release()
        self.tlock.release()

    def __enter__(self):
        """ Context handler, acquires lock in blocking mode. """
        self.acquire()
        return self

    def __exit__(self, _type, value, traceback):
        """ Releases the lock. """
        self.release()

@@ -1,12 +1,592 @@
+# Copyright 2018 Mycroft AI Inc.%0A#%0A# Licensed under the Apache License, Version 2.0 (the %22License%22);%0A# you may not use this file except in compliance with the License.%0A# You may obtain a copy of the License at%0A#%0A#    http://www.apache.org/licenses/LICENSE-2.0%0A#%0A# Unless required by applicable law or agreed to in writing, software%0A# distributed under the License is distributed on an %22AS IS%22 BASIS,%0A# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A# See the License for the specific language governing permissions and%0A# limitations under the License.%0A#%0A
 from threadi
@@ -652,16 +652,64 @@
 essLock%0A
+from os.path import exists%0Afrom os import chmod%0A
 %0A%0Aclass 
@@ -768,42 +768,337 @@
 ock.
- %22%22%22%0A    def __init__(self, path):
+%0A%0A    Arguments:%0A        path (str): path to the lockfile for the lock%0A    %22%22%22%0A    def __init__(self, path):%0A        # Create lock file if it doesn't exist and set permissions for%0A        # all users to lock/unlock%0A        if not exists(path):%0A            f = open(path, 'w+')%0A            f.close()%0A            chmod(path, 0o777)
 %0A   

Make the combo lock handle multiple users (#1828)