Esempio n. 1
0
void
flockfile(FILE * fp)
{
	int	idx = file_idx(fp);
	struct	file_lock	*p;

	/* Lock the hash table: */
	_SPINLOCK(&hash_lock);

	/* Check if the static array has not been initialised: */
	if (!init_done) {
		/* Initialise the global array: */
		memset(flh,0,sizeof(flh));

		/* Flag the initialisation as complete: */
		init_done = 1;
	}

	/* Get a pointer to any existing lock for the file: */
	if ((p = find_lock(idx, fp)) == NULL) {
		/*
		 * The file is not locked, so this thread can
		 * grab the lock:
		 */
		p = do_lock(idx, fp);

		/* Unlock the hash table: */
		_SPINUNLOCK(&hash_lock);

	/*
	 * The file is already locked, so check if the
	 * running thread is the owner:
	 */
	} else if (p->owner == _thread_run) {
		/*
		 * The running thread is already the
		 * owner, so increment the count of
		 * the number of times it has locked
		 * the file:
		 */
		p->count++;

		/* Unlock the hash table: */
		_SPINUNLOCK(&hash_lock);
	} else {
		/*
		 * The file is locked for another thread.
		 * Append this thread to the queue of
		 * threads waiting on the lock.
		 */
		TAILQ_INSERT_TAIL(&p->l_head,_thread_run,qe);

		/* Unlock the hash table: */
		_SPINUNLOCK(&hash_lock);

		/* Wait on the FILE lock: */
		_thread_kern_sched_state(PS_FILE_WAIT, "", 0);
	}
}
Esempio n. 2
0
int
(ftrylockfile)(FILE * fp)
{
    int	ret = -1;
    int	idx = file_idx(fp);
    struct	file_lock	*p;

    /* Lock the hash table: */
    _spinlock(&hash_lock);

    /* Get a pointer to any existing lock for the file: */
    if ((p = find_lock(idx, fp)) == NULL) {
        /*
         * The file is not locked, so this thread can
         * grab the lock:
         */
        p = do_lock(idx, fp);

        /*
         * The file is already locked, so check if the
         * running thread is the owner:
         */
    } else if (p->owner == pthread_self()) {
        /*
         * The running thread is already the
         * owner, so increment the count of
         * the number of times it has locked
         * the file:
         */
        p->count++;
    } else {
        /*
         * The file is locked for another thread,
         * so this try fails.
         */
        p = NULL;
    }

    /* Unlock the hash table: */
    _spinunlock(&hash_lock);

    /* Check if the lock was obtained: */
    if (p != NULL)
        /* Return success: */
        ret = 0;

    return (ret);
}
Esempio n. 3
0
void
(flockfile)(FILE * fp)
{
    int	idx = file_idx(fp);
    struct	file_lock	*p;
    pthread_t	self = pthread_self();

    /* Lock the hash table: */
    _spinlock(&hash_lock);

    /* Get a pointer to any existing lock for the file: */
    if ((p = find_lock(idx, fp)) == NULL) {
        /*
         * The file is not locked, so this thread can
         * grab the lock:
         */
        do_lock(idx, fp);

        /*
         * The file is already locked, so check if the
         * running thread is the owner:
         */
    } else if (p->owner == self) {
        /*
         * The running thread is already the
         * owner, so increment the count of
         * the number of times it has locked
         * the file:
         */
        p->count++;
    } else {
        /*
         * The file is locked for another thread.
         * Append this thread to the queue of
         * threads waiting on the lock.
         */
        TAILQ_INSERT_TAIL(&p->lockers,self,waiting);
        while (p->owner != self) {
            __thrsleep(self, 0 | _USING_TICKETS, NULL,
                       &hash_lock.ticket, NULL);
            _spinlock(&hash_lock);
        }
    }

    /* Unlock the hash table: */
    _spinunlock(&hash_lock);
}
Esempio n. 4
0
void
(funlockfile)(FILE * fp)
{
    int	idx = file_idx(fp);
    struct	file_lock	*p;

    /* Lock the hash table: */
    _spinlock(&hash_lock);

    /*
     * Get a pointer to the lock for the file and check that
     * the running thread is the one with the lock:
     */
    if ((p = find_lock(idx, fp)) != NULL && p->owner == pthread_self()) {
        /*
         * Check if this thread has locked the FILE
         * more than once:
         */
        if (--p->count == 0) {
            /* Get the new owner of the lock: */
            if ((p->owner = TAILQ_FIRST(&p->lockers)) != NULL) {
                /* Pop the thread off the queue: */
                TAILQ_REMOVE(&p->lockers,p->owner,waiting);

                /*
                 * This is the first lock for the new
                 * owner:
                 */
                p->count = 1;

                __thrwakeup(p->owner, 1);
            }
        }
    }

    /* Unlock the hash table: */
    _spinunlock(&hash_lock);
}
Esempio n. 5
0
void 
funlockfile(FILE * fp)
{
	int	idx = file_idx(fp);
	struct	file_lock	*p;

	/*
	 * Defer signals to protect the scheduling queues from
	 * access by the signal handler:
	 */
	_thread_kern_sig_defer();

	/* Lock the hash table: */
	_SPINLOCK(&hash_lock);

	/*
	 * Get a pointer to the lock for the file and check that
	 * the running thread is the one with the lock:
	 */
	if ((p = find_lock(idx, fp)) != NULL &&
	    p->owner == _thread_run) {
		/*
		 * Check if this thread has locked the FILE
		 * more than once:
		 */
		if (p->count > 1)
			/*
			 * Decrement the count of the number of
			 * times the running thread has locked this
			 * file:
			 */
			p->count--;
		else {
			/*
			 * The running thread will release the
			 * lock now:
			 */
			p->count = 0;

			/* Get the new owner of the lock: */
			if ((p->owner = TAILQ_FIRST(&p->l_head)) != NULL) {
				/* Pop the thread off the queue: */
				TAILQ_REMOVE(&p->l_head,p->owner,qe);

				/*
				 * This is the first lock for the new
				 * owner:
				 */
				p->count = 1;

				/* Allow the new owner to run: */
				PTHREAD_NEW_STATE(p->owner,PS_RUNNING);
			}
		}
	}

	/* Unlock the hash table: */
	_SPINUNLOCK(&hash_lock);

	/*
	 * Undefer and handle pending signals, yielding if
	 * necessary:
	 */
	_thread_kern_sig_undefer();
}