-
-
Save sjkillen/291b2815739abb3430b042bf658fb661 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Spencer Killen | |
* CMPT 360 | |
* Assignment 3 | |
* Dec 5th 2016 | |
* Library used for applying a file lock after a condition is met | |
*/ | |
#include <sys/inotify.h> | |
#include <aio.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <fcntl.h> | |
#include <assert.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include "deferred_lock.h" | |
// stores data needed for monitoring a file asynchronously | |
struct file_monitor { | |
struct aiocb async; | |
int infd; | |
int inwd; | |
struct deferred_file_lock *deferred; | |
struct inotify_event *event; | |
}; | |
// called by inotify file events, handles checking lock prereq and applying file lock | |
void file_event(union sigval val) | |
{ | |
struct file_monitor *monitor = (struct file_monitor *) val.sival_ptr; | |
if (monitor->deferred->check_cond(monitor->deferred->data, monitor->event->mask)) { | |
printf("Locking file %d\n", monitor->deferred->fd); | |
int lock = lockf(monitor->deferred->fd, F_LOCK, 0); | |
assert(lock == 0); | |
monitor->deferred->lock_notify(lock, monitor->deferred->fd); | |
assert(inotify_rm_watch(monitor->infd, monitor->inwd) == 0); | |
free(monitor->event); | |
free(monitor); | |
} else { | |
memset(monitor->event, 0, sizeof(struct inotify_event)); | |
assert(aio_read(&monitor->async) == 0); | |
} | |
} | |
void defer_lock(struct deferred_file_lock *lock_block) | |
{ | |
assert(lock_block != NULL); | |
struct file_monitor *monitor = malloc(sizeof(struct file_monitor)); | |
assert(monitor != NULL); | |
monitor->event = malloc(sizeof(struct inotify_event)); | |
assert(monitor->event != NULL); | |
monitor->deferred = lock_block; | |
monitor->infd = inotify_init(); | |
assert(monitor->infd >= 0); | |
monitor->inwd = inotify_add_watch(monitor->infd, | |
monitor->deferred->file, | |
monitor->deferred->in_event); | |
assert(monitor->inwd >= 0); | |
monitor->async = (struct aiocb) { | |
.aio_fildes = monitor->infd, | |
.aio_offset = 0, | |
.aio_buf = monitor->event, | |
.aio_nbytes = sizeof(struct inotify_event), | |
.aio_reqprio = 0, | |
.aio_sigevent = (struct sigevent) { | |
.sigev_notify = SIGEV_THREAD, | |
.sigev_notify_function = file_event, | |
.sigev_notify_attributes = NULL, | |
.sigev_value = (union sigval) { | |
.sival_ptr = monitor | |
} | |
} | |
}; | |
assert(aio_read(&monitor->async) == 0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment