def acquire_pid_lock(self):
            """Atomically acquire the lock on the pid file, if no one else has the lock.

            If the file does not exist, this call will create it.  If the file does exist, its contents
            are not changed until ``write_pid`` is actually invoked.

            You do not need to invoke this before ``write_pid``.  If it has not been invoked, ``write_pid`` will
            acquire the lock.

            This can be used by a parent process to lock the pidfile and then have a forked child process actually
            write its pid to the pidfile.

            This method is guaranteed to not give false positive (saying you have the lock when there is another
            process has it).

            @return:  If the lock was acquired, then a function that, when invoked, will release the lock.  If
                the lock was not acquired, None.  Note, you may disregard the returned function if you subsequently
                invoke ``write_pid``.  IMPORTANT:  Do not release the lock on the pidfile until the agent process
                terminates.
            @rtype: Func
            """
            # By the time we leave this method, we must either have a lock on the file
            # or we saw that the file exists and we could not get the lock on it.

            # Note, it's important to call read_pid to see if it things an agent is running since ``read_pid``
            # checks legancy pid methods, whereas the code below only checks the current pid scheme.
            if self.__manager.read_pid() is not None:
                return None

            # Check if file exists, and if not, we have to be sure to create exclusively... we have to guarantee
            # that there is only one inode out there for this file among all processes ... we can't create the
            # file in one process, get an fd for it, and then have another process create the file again (unknowningly
            # overwriting the first one) and get another fd for it.  That would mean they would be getting locks on
            # different files.
            fd = None
            """ @type: int"""
            if not os.path.isfile(self.__pidfile):
                try:
                    self._log_debug('Creating pidfile')
                    fd = os.open(self.__pidfile, os.O_CREAT | os.O_EXCL | os.O_WRONLY)
                except OSError, e:
                    if e.errno != errno.EEXIST:
                        raise e

            if fd is None:
                try:
                    # If the file already exist, open it for write.. but be sure not to create it if it does not
                    # exist.  That would mean someone, since our os.path.isfile check deleted it... which means
                    # an agent just finished... we pretend like we got a colision and couldn't become the agent.
                    fd = os.open(self.__pidfile, os.O_WRONLY)
                    self._log_debug('Opened pidfile for writing')
                except __HOLE__, e:
                    if e.errno == errno.ENOENT:
                        # Someone just deleted the pid file.. an agent is just finishing, so just say we couldn't
                        # acquire the lock.
                        self._log('Acquire pidfile failed*')
                        return None
                    else:
                        raise e

            fp = None
            try:
                try:
                    # Grab the lock on the file if possible.
                    fp = os.fdopen(fd, 'w')
                    fcntl.flock(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
                except IOError, e:
                    if (e.errno == errno.EAGAIN) or (e.errno == errno.EACCES):
                        # Someone else had the lock.
                        self._log('Acquire pidfile failed-')
                        return None
                    else:
                        raise e

                self.__locked_fd = fp
                self._log('Acquire succeeded')
                fp = None
                fd = None
                return self.__release_lock
            finally:
                if fp is not None:
                    fp.close()
                elif fd is not None:
                    os.close(fd)
dataset/ETHPy150Open scalyr/scalyr-agent-2/scalyr_agent/platform_posix.py/PidfileManager.PidWriter.acquire_pid_lock