| 870 | /* ── Watcher lifecycle ──────────────────────────────────────────── */ |
| 871 | |
| 872 | cbm_watcher_t *cbm_watcher_new(cbm_store_t *store, cbm_index_fn index_fn, void *user_data) { |
| 873 | cbm_watcher_t *w = calloc(CBM_ALLOC_ONE, sizeof(*w)); |
| 874 | if (!w) { |
| 875 | return NULL; |
| 876 | } |
| 877 | w->store = store; |
| 878 | w->index_fn = index_fn; |
| 879 | w->user_data = user_data; |
| 880 | w->projects = cbm_ht_create(CBM_SZ_32); |
| 881 | if (!w->projects) { |
| 882 | free(w); |
| 883 | return NULL; |
| 884 | } |
| 885 | cbm_mutex_init(&w->projects_lock); |
| 886 | cbm_mutex_init(&w->coordination_lock); |
| 887 | atomic_init(&w->stopped, 0); |
| 888 | return w; |
| 889 | } |
| 890 | |
| 891 | void cbm_watcher_free(cbm_watcher_t *w) { |
| 892 | if (!w) { |