Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8be0335c authored by Josh Guilfoyle's avatar Josh Guilfoyle
Browse files

Switched FileLock to use fcntl for compatability with the Java layer.

The Java layer (i.e. Harmony) is currently implementing FileLock this
way so we are aligning to be compatable with locks created from
FileChannel#lock.  This code is therefore fragile and depends on deep
implementation details of Harmony.  For this reason, this solution
should be replaced with something more reliable.
parent e7d27e5e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ public:
     * Lock the file.  A balanced call to unlock is required even if the lock
     * fails.
     */
    bool lock(int openFlags=O_RDONLY, mode_t fileCreateMode=0755) {
    bool lock(int openFlags=O_RDWR, mode_t fileCreateMode=0755) {
        mRefCount++;
        if (mFd == -1) {
            return doLock(openFlags, fileCreateMode);
+26 −9
Original line number Diff line number Diff line
@@ -41,6 +41,19 @@ FileLock::FileLock(const char* fileName)
    assert(mFileName != NULL);
}

static struct flock fullfileLock(short lockType)
{
    struct flock lock;
    memset(&lock, 0, sizeof(lock));

    lock.l_type = lockType;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    return lock;
}

/*
 * Destructor.
 */
@@ -48,17 +61,18 @@ FileLock::~FileLock(void)
{
    assert(mRefCount == 0);

    if (mFileName != NULL) {
        free(mFileName);
    }
    if (mFd >= 0) {
        if (flock(mFd, LOCK_UN) != 0) {
            LOGE("flock(%s,LOCK_UN) failed: %s\n", mFileName, strerror(errno));
        struct flock lock(fullfileLock(F_UNLCK));
        if (fcntl(mFd, F_SETLK, &lock) == -1) {
            LOGE("error releasing write lock on %s: %s\n", mFileName, strerror(errno));
        }
        if (close(mFd) != 0) {
            LOGE("close(%s) failed: %s\n", mFileName, strerror(errno));
        }
    }
    if (mFileName != NULL) {
        free(mFileName);
    }
}

bool FileLock::doLock(int openFlags, mode_t fileCreateMode)
@@ -68,11 +82,14 @@ bool FileLock::doLock(int openFlags, mode_t fileCreateMode)
        return false;
    }

    if (flock(fd, LOCK_EX) != 0) {
        LOGE("flock(%s,LOCK_EX) failed: %s\n", mFileName, strerror(errno));
    struct flock lock(fullfileLock(F_WRLCK));
    while (fcntl(fd, F_SETLKW, &lock) == -1) {
        if (errno != EINTR) {
            LOGE("error acquiring write lock on %s: %s\n", mFileName, strerror(errno));
            close(fd);
            return false;
        }
    }

    mFd = fd;
    return true;