93 lines
2.6 KiB
C
93 lines
2.6 KiB
C
#include "TimerFileWatcher.h"
|
|
|
|
#include <glib.h>
|
|
#include <glib/gstdio.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <time.h>
|
|
|
|
struct _TimerFileWatcher {
|
|
GObject parent;
|
|
|
|
char *path;
|
|
|
|
GThread *thread;
|
|
gboolean running;
|
|
|
|
time_t lastTime;
|
|
};
|
|
|
|
G_DEFINE_TYPE(TimerFileWatcher, timer_file_watcher, G_TYPE_OBJECT);
|
|
|
|
static void timer_file_watcher_tick(TimerFileWatcher *self) {
|
|
gint64 last_tick = 0;
|
|
GStatBuf statbuf;
|
|
while (self->running) {
|
|
gint64 now = g_get_monotonic_time();
|
|
if ((now - last_tick) > (G_USEC_PER_SEC * FILE_WATCHER_POLL_RATE) && g_stat(self->path, &statbuf) == 0) {
|
|
if (self->lastTime != statbuf.st_atime) {
|
|
g_signal_emit_by_name(self, "file-changed");
|
|
self->lastTime = statbuf.st_atime;
|
|
}
|
|
last_tick = now;
|
|
}
|
|
g_usleep(500);
|
|
}
|
|
}
|
|
|
|
TimerFileWatcher *timer_file_watcher_new(const char *path) {
|
|
TimerFileWatcher *fw = g_object_new(TIMER_TYPE_FILE_WATCHER, NULL);
|
|
GStatBuf statbuf;
|
|
if (g_stat(path, &statbuf) == 0) {
|
|
fw->lastTime = statbuf.st_atime;
|
|
}
|
|
fw->path = g_strdup(path);
|
|
fw->running = TRUE;
|
|
fw->thread = g_thread_new(NULL, (GThreadFunc) timer_file_watcher_tick, fw);
|
|
return fw;
|
|
}
|
|
|
|
const char *timer_file_watcher_get_path(TimerFileWatcher* self) {
|
|
return self->path;
|
|
}
|
|
|
|
void timer_file_watcher_pause(TimerFileWatcher *self) {
|
|
if (self->running) {
|
|
self->running = FALSE;
|
|
g_thread_join(self->thread);
|
|
g_thread_unref(self->thread);
|
|
}
|
|
}
|
|
|
|
void timer_file_watcher_resume(TimerFileWatcher *self, gboolean update) {
|
|
if (!self->running) {
|
|
self->running = TRUE;
|
|
if (!update) {
|
|
GStatBuf statbuf;
|
|
if (g_stat(self->path, &statbuf) == 0) {
|
|
self->lastTime = statbuf.st_atime;
|
|
}
|
|
}
|
|
self->thread = g_thread_new(NULL, (GThreadFunc) timer_file_watcher_tick, self);
|
|
}
|
|
}
|
|
|
|
gboolean timer_file_watcher_is_paused(TimerFileWatcher *self) {
|
|
return !self->running;
|
|
}
|
|
|
|
static void timer_file_watcher_finalize(GObject *self) {
|
|
g_free(TIMER_FILE_WATCHER(self)->path);
|
|
timer_file_watcher_pause(TIMER_FILE_WATCHER(self));
|
|
G_OBJECT_CLASS(timer_file_watcher_parent_class)->finalize(self);
|
|
}
|
|
|
|
static void timer_file_watcher_class_init(TimerFileWatcherClass *class) {
|
|
g_signal_new("file-changed", TIMER_TYPE_FILE_WATCHER, G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
|
|
0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
|
G_OBJECT_CLASS(class)->finalize = timer_file_watcher_finalize;
|
|
}
|
|
|
|
static void timer_file_watcher_init(TimerFileWatcher *self) {
|
|
}
|