Skip to content

Commit

Permalink
Replace worker-sets with red-black tree of watches
Browse files Browse the repository at this point in the history
Inode number is unique now so we can store kqueue watches in key->value format
where key is an inode number.
TODO: consider import one of hash table implementations e.g. utlhash
  • Loading branch information
wulf7 committed Jan 29, 2015
1 parent 6e28faf commit bfb6346
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 225 deletions.
1 change: 0 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ libinotify_la_SOURCES = \
dep-list.c \
inotify-watch.c \
watch.c \
worker-sets.c \
worker-thread.c \
worker.c \
controller.c
Expand Down
6 changes: 6 additions & 0 deletions compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@
SLIST_NEXT(SLIST_NEXT(elm, field), field); \
} while (0)
#endif
#ifndef RB_FOREACH_SAFE
#define RB_FOREACH_SAFE(x, name, head, y) \
for ((x) = RB_MIN(name, head); \
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
(x) = (y))
#endif
#endif /* BUILD_LIBRARY */

#ifndef HAVE_PTHREAD_BARRIER
Expand Down
59 changes: 16 additions & 43 deletions inotify-watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include "inotify-watch.h"
#include "utils.h"
#include "watch.h"
#include "worker-sets.h"

/**
* Initialize kqueue watch and insert it into inotify watch`s watchlist
Expand All @@ -52,20 +51,12 @@ iwatch_ins_watch (i_watch *iw, int fd, watch_type_t type)
{
assert (iw != NULL);

if (worker_sets_extend (&iw->watches, 1) == -1) {
perror_msg ("Failed to extend worker sets");
return NULL;
}

watch *w = watch_init (iw, type, fd);

if (w == NULL) {
return NULL;
if (w != NULL) {
++w->refcount;
RB_INSERT (watch_tree, &iw->watches, w);
}
++w->refcount;
iw->watches.watches[iw->watches.length] = w;

++iw->watches.length;

return w;
}
Expand Down Expand Up @@ -135,17 +126,10 @@ iwatch_init (worker *wrk, int fd, uint32_t flags)
iw->inode = st.st_ino;
iw->dev = st.st_dev;

if (worker_sets_init (&iw->watches) == -1) {
if (S_ISDIR (st.st_mode)) {
dl_free (deps);
}
free (iw);
return NULL;
}
RB_INIT (&iw->watches);

watch *parent = iwatch_ins_watch (iw, fd, WATCH_USER);
if (parent == NULL) {
worker_sets_free (&iw->watches);
if (S_ISDIR (st.st_mode)) {
dl_free (deps);
}
Expand Down Expand Up @@ -177,7 +161,12 @@ iwatch_free (i_watch *iw)
{
assert (iw != NULL);

worker_sets_free (&iw->watches);
watch *w, *tmp;
RB_FOREACH_SAFE (w, watch_tree, &iw->watches, tmp) {
RB_REMOVE (watch_tree, &iw->watches, w);
watch_free (w);
}

if (iw->deps != NULL) {
dl_free (iw->deps);
}
Expand All @@ -196,17 +185,8 @@ iwatch_find_watch (i_watch *iw, ino_t inode)
{
assert (iw != NULL);

size_t i;

for (i = 0; i < iw->watches.length; i++) {

watch *w = iw->watches.watches[i];
if (inode == w->inode) {
return w;
}
}

return NULL;
watch find = { .inode = inode };
return RB_FIND (watch_tree, &iw->watches, &find);
}

/**
Expand Down Expand Up @@ -262,14 +242,8 @@ iwatch_del_subwatch (i_watch *iw, const dep_item *di)
--w->refcount;

if (w->refcount == 0) {
size_t i;

for (i = 0; i < iw->watches.length; i++) {
if (di->inode == iw->watches.watches[i]->inode) {
worker_sets_delete (&iw->watches, i);
break;
}
}
RB_REMOVE (watch_tree, &iw->watches, w);
watch_free (w);
}
}
}
Expand All @@ -290,9 +264,8 @@ iwatch_update_flags (i_watch *iw, uint32_t flags)

iw->flags = flags;

size_t i;
for (i = 0; i < iw->watches.length; i++) {
watch *w = iw->watches.watches[i];
watch *w;
RB_FOREACH (w, watch_tree, &iw->watches) {
uint32_t fflags = inotify_to_kqueue (flags,
w->flags & WF_ISDIR,
w->flags & WF_ISSUBWATCH);
Expand Down
5 changes: 3 additions & 2 deletions inotify-watch.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@

typedef struct i_watch i_watch;

#include "compat.h"
#include "dep-list.h"
#include "watch.h"
#include "worker.h"
#include "worker-sets.h"

struct i_watch {
int wd; /* watch descriptor */
Expand All @@ -39,7 +40,7 @@ struct i_watch {
ino_t inode; /* inode number of watched inode */
dev_t dev; /* device number of watched inode */
dep_list *deps; /* dependence list of inotify watch */
worker_sets watches; /* kqueue watches of inotify watch */
watch_tree watches; /* kqueue watches of inotify watch */
SLIST_ENTRY(i_watch) next; /* pointer to the next inotify watch in list */
};

Expand Down
17 changes: 17 additions & 0 deletions watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@ _file_information (int fd, int *is_dir, ino_t *inode)
}
}

/**
* Custom comparison function that can compare kqueue watch inode values
* through pointers passed by RB tree functions
*
* @param[in] w1 A pointer to a first kqueue watch to compare
* @param[in] w2 A pointer to a second kqueue watch to compare
* @return An -1, 0, or +1 if the first watch is considered to be respectively
* less than, equal to, or greater than the second one.
**/
static int
watch_cmp (watch *w1, watch *w2)
{
return ((w1->inode > w2->inode) - (w1->inode < w2->inode));
}

/* struct kevent is declared slightly differently on the different BSDs.
* This macros will help to avoid cast warnings on the supported platforms. */
#if defined (__NetBSD__)
Expand Down Expand Up @@ -193,3 +208,5 @@ watch_free (watch *w)
}
free (w);
}

RB_GENERATE(watch_tree, watch, link, watch_cmp);
5 changes: 5 additions & 0 deletions watch.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
#include <dirent.h> /* ino_t */

typedef struct watch watch;
typedef RB_HEAD(watch_tree, watch) watch_tree;

#include "compat.h" /* RB tree macroses */
#include "inotify-watch.h"

#define WF_ISSUBWATCH (1<<0) /* a type of watch */
Expand All @@ -46,6 +48,7 @@ struct watch {
* to that watch */
int fd; /* file descriptor of a watched entry */
ino_t inode; /* inode number for the watched entry */
RB_ENTRY(watch) link; /* RB tree links */
};

int watch_open (int dirfd, const char *path, uint32_t flags);
Expand All @@ -54,4 +57,6 @@ void watch_free (watch *w);

int watch_register_event (watch *w, uint32_t fflags);

RB_PROTOTYPE(watch_tree, watch, link, watch_cmp);

#endif /* __WATCH_H__ */
136 changes: 0 additions & 136 deletions worker-sets.c

This file was deleted.

43 changes: 0 additions & 43 deletions worker-sets.h

This file was deleted.

0 comments on commit bfb6346

Please sign in to comment.