watcher: misc fix

- The initial `impl_rearm()` should always be performed by the
  worker thread, so that we won't get spurious zero returns from
  `watcher_poll()`.
- Sandboxing should not be implicitly disabled if not implemented.
- Shift internal watcher flags, to save space for public ones
  if we wish to add any in the future.
This commit is contained in:
CismonX 2025-03-02 06:54:06 +08:00
parent 8cbd5846d9
commit b1100445b7
No known key found for this signature in database
GPG key ID: 3094873E29A482FB
2 changed files with 17 additions and 16 deletions

View file

@ -47,8 +47,8 @@
#include "sandbox.h"
#include "xstd.h"
#define WATCHER_DEAD ( 1u << 2 )
#define WATCHER_IDLE ( 1u << 3 )
#define WATCHER_DEAD ( 1u << 8 )
#define WATCHER_IDLE ( 1u << 9 )
// This value is chosen according to how frequent Chromium saves its bookmarks
// (`bookmarks::BookmarkStorage::kSaveDelay`).
@ -311,7 +311,6 @@ worker_loop (
pthread_mutex_lock(&w->mutex);
#ifdef BOOKMARKFS_SANDBOX
uint32_t sandbox_flags = w->flags >> WATCHER_SANDBOX_FLAGS_OFFSET;
if (!(sandbox_flags & SANDBOX_NOOP)) {
sandbox_flags |= SANDBOX_READONLY;
@ -320,13 +319,17 @@ worker_loop (
}
debug_puts("worker thread enters sandbox");
}
#endif /* defined(BOOKMARKFS_SANDBOX) */
debug_puts("worker ready");
do {
w->flags |= WATCHER_IDLE;
pthread_cond_wait(&w->cond, &w->mutex);
} while (0 == impl_watch(w));
switch (impl_rearm(w)) {
case 0:
debug_puts("worker ready");
while (0 == impl_watch(w)) {
// fallthrough
case -ENOENT:
w->flags |= WATCHER_IDLE;
pthread_cond_wait(&w->cond, &w->mutex);
}
}
end:
w->flags |= (WATCHER_DEAD | WATCHER_IDLE);

View file

@ -52,11 +52,6 @@ do_check_watcher (
#define ASSERT_EQ(val, expr) ASSERT_EXPR((val) == (expr), goto end;)
#define ASSERT_NE(val, expr) ASSERT_EXPR((val) != (expr), goto end;)
struct watcher *w = watcher_create(dirfd, FILE1_NAME, flags);
if (w == NULL) {
return -1;
}
unsigned long msecs = 100;
int tries = 5;
if (flags & WATCHER_FALLBACK) {
@ -71,8 +66,11 @@ do_check_watcher (
fd = openat(dirfd, FILE1_NAME, O_WRONLY | O_CREAT, 0600);
ASSERT_NE(-1, fd);
// Lazy-init watcher.
ASSERT_EQ(0, wait_for_watcher(w, &ts, tries));
struct watcher *w = watcher_create(dirfd, FILE1_NAME, flags);
ASSERT_NE(NULL, w);
// Check for spurious zero returns.
ASSERT_EQ(-ETIMEDOUT, wait_for_watcher(w, &ts, tries));
ASSERT_NE(-1, write(fd, "foo", 3));
ASSERT_EQ(0, wait_for_watcher(w, &ts, tries));