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

Function prune_missing_project

src/watcher/watcher.c:1156–1219  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1154} poll_ctx_t;
1155
1156static void prune_missing_project(cbm_watcher_t *w, project_state_t *s) {
1157 if (!w || !s || !s->project_name) {
1158 return;
1159 }
1160
1161 char *project_name = cbm_strdup(s->project_name);
1162 char *root_path = cbm_strdup(s->root_path);
1163 if (!project_name || !root_path) {
1164 free(project_name);
1165 free(root_path);
1166 return;
1167 }
1168
1169 bool removed = false;
1170 cbm_mutex_lock(&w->coordination_lock);
1171 bool mutation_acquired =
1172 !w->mutation_begin || w->mutation_begin(w->mutation_context, project_name);
1173 if (!mutation_acquired) {
1174 cbm_mutex_unlock(&w->coordination_lock);
1175 free(project_name);
1176 free(root_path);
1177 return;
1178 }
1179 cbm_mutex_lock(&w->projects_lock);
1180 project_state_t *current = cbm_ht_get(w->projects, project_name);
1181 /* Deferred free (same discipline as cbm_watcher_unwatch): this state
1182 * is referenced by the poll_once snapshot iterating us. On OOM the
1183 * watch stays registered and pruning retries on the next cycle. Re-stat
1184 * under the mutation lease so a root restored after the poll snapshot is
1185 * never pruned. */
1186 int stat_errno = 0;
1187 uint64_t now_ms = cbm_now_ms();
1188 bool still_eligible =
1189 current == s && strcmp(current->root_path, root_path) == 0 &&
1190 current->missing_root_count >= MISSING_ROOT_DELETE_AFTER && current->first_missing_ms > 0 &&
1191 now_ms - current->first_missing_ms >= (uint64_t)prune_grace_s() * CBM_MSEC_PER_SEC &&
1192 root_status(root_path, &stat_errno) == ROOT_MISSING;
1193 if (still_eligible && defer_state_free(w, s)) {
1194 if (delete_cached_project_db(project_name)) {
1195 atomic_store_explicit(&s->registered, false, memory_order_release);
1196 cbm_ht_delete(w->projects, project_name);
1197 removed = true;
1198 } else {
1199 /* The state stays registered; undo the just-added deferred-free
1200 * entry so the next poll can safely retry the failed deletion. */
1201 w->pending_free[--w->pending_free_count] = NULL;
1202 }
1203 }
1204 cbm_mutex_unlock(&w->projects_lock);
1205
1206 if (removed && w->project_pruned) {
1207 w->project_pruned(w->mutation_context, project_name);
1208 }
1209 if (w->mutation_begin) {
1210 w->mutation_end(w->mutation_context, project_name);
1211 }
1212 cbm_mutex_unlock(&w->coordination_lock);
1213

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