/** Helper: Put <b>entry</b> into map of directory requests using * <b>type</b> and <b>dirreq_id</b> as key parts. If there is * already an entry for that key, print out a BUG warning and return. */ static void dirreq_map_put_(dirreq_map_entry_t *entry, dirreq_type_t type, uint64_t dirreq_id) { dirreq_map_entry_t *old_ent; tor_assert(entry->type == type); tor_assert(entry->dirreq_id == dirreq_id); /* XXXX we could switch this to HT_INSERT some time, since it seems that * this bug doesn't happen. But since this function doesn't seem to be * critical-path, it's sane to leave it alone. */ old_ent = HT_REPLACE(dirreqmap, &dirreq_map, entry); if (old_ent && old_ent != entry) { log_warn(LD_BUG, "Error when putting directory request into local " "map. There was already an entry for the same identifier."); return; } }
/** * Begin monitoring the child pid <b>pid</b> to see if we get a SIGCHLD for * it. If we eventually do, call <b>fn</b>, passing it the exit status (as * yielded by waitpid) and the pointer <b>arg</b>. * * To cancel this, or clean up after it has triggered, call * clear_waitpid_callback(). */ waitpid_callback_t * set_waitpid_callback(pid_t pid, void (*fn)(int, void *), void *arg) { waitpid_callback_t *old_ent; waitpid_callback_t *ent = tor_malloc_zero(sizeof(waitpid_callback_t)); ent->pid = pid; ent->userfn = fn; ent->userdata = arg; ent->running = 1; old_ent = HT_REPLACE(process_map, &process_map, ent); if (old_ent) { log_warn(LD_BUG, "Replaced a waitpid monitor on pid %u. That should be " "impossible.", (unsigned) pid); old_ent->running = 0; } return ent; }