pixelb / crudini

A utility for manipulating ini files
GNU General Public License v2.0
443 stars 60 forks source link

FileLock does not work with system lock #26

Closed vit1251 closed 2 years ago

vit1251 commented 9 years ago

You will use follow code

class FileLock(object):
    """Advisory file based locking.  This should be reasonably cross platform
       and also work over distributed file systems."""
    def __init__(self, exclusive=False):
        # In inplace mode, the process must be careful to not close this fp
        # until finished, nor open and close another fp associated with the
        # file.
        self.fp = None
        self.locked = False

        if os.name == 'nt':
            import msvcrt

            def lock(self):
                msvcrt.locking(self.fp.fileno(), msvcrt.LK_LOCK, 1)
                self.locked = True

            def unlock(self):
                if self.locked is True:
                    msvcrt.locking(self.fp.fileno(), msvcrt.LK_UNLCK, 1)
                self.locked = False

Also

                while True:
                    self.lock()
                    fpnew = os.fdopen(os.open(self.filename, open_mode, 0o666))
                    if os.path.sameopenfile(self.fp.fileno(), fpnew.fileno()):

It does not work on WIndows platform!!!

This code have two or three level simplify ready at now...

pixelb commented 9 years ago

Do the msvcrt.locking() calls not work? Does the os.fdopen() call not work? Have you error messages?

vit1251 commented 9 years ago

@pixelb you have in self.fp object and use msvcrt.locking(int) where first argument is fileno (file handle).

Second, windows implementation has no sameopenfile implementation.. And as result you tools does not work.

pixelb commented 9 years ago

Ah I see tricky. The documentation uses the same 'fd' parameter name for lockf() and locking()

As for the sameopenfile() issue, that shouldn't be possible anyway on windows, so can you change that part to:

                if (os.name == 'nt'
                    or os.path.sameopenfile(self.fp.fileno(), fpnew.fileno())):

I'll commit both changes in your name if it works.

thanks!

vit1251 commented 9 years ago

@pixelb usually I create a separate classes int-t from FileLock for example you may Implement WindowsFileLock and PosixFileLock.

N.B. os.path.sameopenfile you really require this call? You may just read all information to memory and write it again back with exclusive lock. And most of INI files must small size and just load in memory.

pixelb commented 9 years ago

Having separate classes seems like a little overkill here. I'll consider cleaning up, though will mean moving the if os == 'nt' call to a higher level.

We need the sameopenfile() check to ensure we're locking on the right file. Note the read() is done after the locking.

pixelb commented 2 years ago

Addressed in commit 0f2c0b03