MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / prune_missing_project

Function prune_missing_project

src/watcher/watcher.c:1303–1366  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1301} poll_ctx_t;
1302
1303static void prune_missing_project(cbm_watcher_t *w, project_state_t *s) {
1304 if (!w || !s || !s->project_name) {
1305 return;
1306 }
1307
1308 char *project_name = cbm_strdup(s->project_name);
1309 char *root_path = cbm_strdup(s->root_path);
1310 if (!project_name || !root_path) {
1311 free(project_name);
1312 free(root_path);
1313 return;
1314 }
1315
1316 bool removed = false;
1317 cbm_mutex_lock(&w->coordination_lock);
1318 bool mutation_acquired =
1319 !w->mutation_begin || w->mutation_begin(w->mutation_context, project_name);
1320 if (!mutation_acquired) {
1321 cbm_mutex_unlock(&w->coordination_lock);
1322 free(project_name);
1323 free(root_path);
1324 return;
1325 }
1326 cbm_mutex_lock(&w->projects_lock);
1327 project_state_t *current = cbm_ht_get(w->projects, project_name);
1328 /* Deferred free (same discipline as cbm_watcher_unwatch): this state
1329 * is referenced by the poll_once snapshot iterating us. On OOM the
1330 * watch stays registered and pruning retries on the next cycle. Re-stat
1331 * under the mutation lease so a root restored after the poll snapshot is
1332 * never pruned. */
1333 int stat_errno = 0;
1334 uint64_t now_ms = cbm_now_ms();
1335 bool still_eligible =
1336 current == s && strcmp(current->root_path, root_path) == 0 &&
1337 current->missing_root_count >= MISSING_ROOT_DELETE_AFTER && current->first_missing_ms > 0 &&
1338 now_ms - current->first_missing_ms >= (uint64_t)prune_grace_s() * CBM_MSEC_PER_SEC &&
1339 root_status(root_path, &stat_errno) == ROOT_MISSING;
1340 if (still_eligible && defer_state_free(w, s)) {
1341 if (delete_cached_project_db(project_name)) {
1342 atomic_store_explicit(&s->registered, false, memory_order_release);
1343 cbm_ht_delete(w->projects, project_name);
1344 removed = true;
1345 } else {
1346 /* The state stays registered; undo the just-added deferred-free
1347 * entry so the next poll can safely retry the failed deletion. */
1348 w->pending_free[--w->pending_free_count] = NULL;
1349 }
1350 }
1351 cbm_mutex_unlock(&w->projects_lock);
1352
1353 if (removed && w->project_pruned) {
1354 w->project_pruned(w->mutation_context, project_name);
1355 }
1356 if (w->mutation_begin) {
1357 w->mutation_end(w->mutation_context, project_name);
1358 }
1359 cbm_mutex_unlock(&w->coordination_lock);
1360

Callers 1

poll_projectFunction · 0.85

Calls 9

cbm_mutex_lockFunction · 0.85
cbm_mutex_unlockFunction · 0.85
cbm_ht_getFunction · 0.85
cbm_now_msFunction · 0.85
prune_grace_sFunction · 0.85
root_statusFunction · 0.85
defer_state_freeFunction · 0.85
delete_cached_project_dbFunction · 0.85
cbm_ht_deleteFunction · 0.85

Tested by

no test coverage detected