示例#1
0
/*
 * commit sequence update
 * returns:
 *	0	-> ok
 *	other	-> link failed
 */
int
cmtseq(void)
{
	int ret;

	if ((ret = access(SQTMP, 0)) != 0) {
		rmlock(SQLOCK);
		return (0);
	}
	unlink(SQFILE);
	ret = link(SQTMP, SQFILE);
	unlink(SQTMP);
	rmlock(SQLOCK);
	return (ret);
}
示例#2
0
/*!
    Attempts to create the lock file. This function returns \c true if the
    lock was obtained; otherwise it returns \c false. If another process (or
    another thread) has created the lock file already, this function will
    wait for at most \a timeout milliseconds for the lock file to become
    available.

    Note: Passing a negative number as the \a timeout is equivalent to
    calling lock(), i.e. this function will wait forever until the lock
    file can be locked if \a timeout is negative.

    If the lock was obtained, it must be released with unlock()
    before another process (or thread) can successfully lock it.

    Calling this function multiple times on the same lock from the same
    thread without unlocking first is not allowed, this function will
    \e always return false when attempting to lock the file recursively.

    \sa lock(), unlock()
*/
bool QLockFile::tryLock(int timeout)
{
    Q_D(QLockFile);
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
    QElapsedTimer timer;
#else
    QTime timer;
#endif
    if (timeout > 0)
        timer.start();
    int sleepTime = 100;
    Q_FOREVER {
        d->lockError = d->tryLock_sys();
        switch (d->lockError) {
        case NoError:
            d->isLocked = true;
            return true;
        case PermissionError:
        case UnknownError:
            return false;
        case LockFailedError:
            if (!d->isLocked && d->isApparentlyStale()) {
                // Stale lock from another thread/process
                // Ensure two processes don't remove it at the same time
                QLockFile rmlock(d->fileName + QLatin1String(".rmlock"));
                if (rmlock.tryLock()) {
                    if (d->isApparentlyStale() && d->removeStaleLock())
                        continue;
                }
            }
            break;
        }
        if (timeout == 0 || (timeout > 0 && (timer.elapsed() > timeout)))
            return false;
        QLockFileThread::msleep(sleepTime);
        if (sleepTime < 5 * 1000)
            sleepTime *= 2;
    }
    // not reached
    return false;
}
示例#3
0
/*
 * Open a file, locking using the lock types specified. Returns EAGAIN if lock
 * failed.
 */
int
openlock(const char *path, int flags, u_int locks)
{
	int	fd, saved_errno;

	if (mklock(locks, path) != 0)
		return (-1);
	if ((fd = open(path, flags, 0)) == -1)
		goto error;
	if (lockfd(locks, fd) != 0)
		goto error;

	return (fd);

error:
	saved_errno = errno;
	close(fd);
	rmlock(locks, path);
	errno = saved_errno;
	return (-1);
}
示例#4
0
/* Create a locked file. */
int
createlock(
    const char *path, int flags, uid_t uid, gid_t gid, mode_t mode, u_int locks)
{
	int	fd, saved_errno;

	if (mklock(locks, path) != 0)
		return (-1);
	if ((fd = xcreate(path, flags, uid, gid, mode)) == -1)
		goto error;
	if (lockfd(locks, fd) != 0)
		goto error;

	return (fd);

error:
	saved_errno = errno;
	close(fd);
	rmlock(locks, path);
	errno = saved_errno;
	return (-1);
}
示例#5
0
/*!
    Attempts to create the lock file. This function returns \c true if the
    lock was obtained; otherwise it returns \c false. If another process (or
    another thread) has created the lock file already, this function will
    wait for at most \a timeout milliseconds for the lock file to become
    available.

    Note: Passing a negative number as the \a timeout is equivalent to
    calling lock(), i.e. this function will wait forever until the lock
    file can be locked if \a timeout is negative.

    If the lock was obtained, it must be released with unlock()
    before another process (or thread) can successfully lock it.

    Calling this function multiple times on the same lock from the same
    thread without unlocking first is not allowed, this function will
    \e always return false when attempting to lock the file recursively.

    \sa lock(), unlock()
*/
bool QLockFile::tryLock(int timeout)
{
    Q_D(QLockFile);
    QElapsedTimer timer;
    if (timeout > 0)
        timer.start();
    int sleepTime = 100;
    forever {
        d->lockError = d->tryLock_sys();
        switch (d->lockError) {
        case NoError:
            d->isLocked = true;
            return true;
        case PermissionError:
        case UnknownError:
            return false;
        case LockFailedError:
            if (!d->isLocked && d->isApparentlyStale()) {
                // Stale lock from another thread/process
                // Ensure two processes don't remove it at the same time
                QLockFile rmlock(d->fileName + QStringLiteral(".rmlock"));
                if (rmlock.tryLock()) {
                    if (d->isApparentlyStale() && d->removeStaleLock())
                        continue;
                }
            }
            break;
        }
        if (timeout == 0 || (timeout > 0 && timer.hasExpired(timeout)))
            return false;
        QThread::msleep(sleepTime);
        if (sleepTime < 5 * 1000)
            sleepTime *= 2;
    }
    // not reached
    return false;
}
示例#6
0
/* Close locked file and remove locks. */
void
closelock(int fd, const char *path, u_int locks)
{
	close(fd);
	rmlock(locks, path);
}
示例#7
0
/*
 * get next conversation sequence number
 *	rmtname	-> name of remote system
 * returns:
 *	0	-> no entery
 *	1	-> 0 sequence number
 */
int
gnxseq(char *rmtname)
{
	register FILE *fp0, *fp1;
	register struct tm *tp;
	int count = 0, ct, ret;
	char buf[BUFSIZ], name[NAMESIZE];
	time_t clock;

	if (access(SQFILE, 0) != 0)
		return (0);

	{
		int i;
		for (i = 0; i < 5; i++)
			if ((ret = mklock(SQLOCK)) == SUCCESS)
				break;
		sleep(5);
	}
	if (ret != SUCCESS) {
		logent("CAN'T LOCK", SQLOCK);
		DEBUG(4, "can't lock %s\n", SQLOCK);
		return (0);
	}
	if ((fp0 = fopen(SQFILE, "r")) == NULL)
		return (0);
	if ((fp1 = fopen(SQTMP, "w")) == NULL) {
		fclose(fp0);
		return (0);
	}
	chmod(SQTMP, DFILEMODE);

	while (fgets(buf, BUFSIZ, fp0) != NULL) {
		ret = sscanf(buf, "%s%d", name, &ct);
		if (ret < 2)
			ct = 0;
		name[7] = '\0';
		if (ct > 9998)
			ct = 0;
		if (strncmp(rmtname, name, SYSNSIZE) != SAME) {
			fputs(buf, fp1);
			continue;
		}

		/*
		 * found name
		 */
		count = ++ct;
		time(&clock);
		tp = localtime(&clock);
		fprintf(fp1, "%s %d %d/%d-%d:%2.2d\n", name, ct,
		    tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
		    tp->tm_min);

		/*
		 * write should be checked
		 */
		while (fgets(buf, BUFSIZ, fp0) != NULL)
			fputs(buf, fp1);
	}
	fclose(fp0);
	fclose(fp1);
	if (count == 0) {
		rmlock(SQLOCK);
		unlink(SQTMP);
	}
	return (count);
}
示例#8
0
/*
 * unlock sequence file
 */
void
ulkseq(void)
{
	unlink(SQTMP);
	rmlock(SQLOCK);
}