static void add_to_queue(struct SpawnRequest_t *req) { ASSERT_IS_LOCKED(s_spawn_queue_lock); s_request_queue.push(req); }
/** Save the specified mode to file */ void history_t::save_internal() { /* This must be called while locked */ ASSERT_IS_LOCKED(lock); /* Nothing to do if there's no new items */ if (new_items.empty() && deleted_items.empty()) return; /* Compact our new items so we don't have duplicates */ this->compact_new_items(); bool ok = true; wcstring tmp_name = history_filename(name, L".tmp"); if( ! tmp_name.empty() ) { /* Make an LRU cache to save only the last N elements */ history_lru_cache_t lru(HISTORY_SAVE_MAX); /* Insert old items in, from old to new. Merge them with our new items, inserting items with earlier timestamps first. */ std::vector<history_item_t>::const_iterator new_item_iter = new_items.begin(); /* Map in existing items (which may have changed out from underneath us, so don't trust our old mmap'd data) */ const char *local_mmap_start = NULL; size_t local_mmap_size = 0; if (map_file(name, &local_mmap_start, &local_mmap_size)) { const history_file_type_t local_mmap_type = infer_file_type(local_mmap_start, local_mmap_size); size_t cursor = 0; for (;;) { size_t offset = offset_of_next_item(local_mmap_start, local_mmap_size, local_mmap_type, &cursor, 0); /* If we get back -1, we're done */ if (offset == (size_t)(-1)) break; /* Try decoding an old item */ const history_item_t old_item = history_t::decode_item(local_mmap_start + offset, local_mmap_size - offset, local_mmap_type); if (old_item.empty() || is_deleted(old_item)) { // debug(0, L"Item is deleted : %s\n", old_item.str().c_str()); continue; } /* The old item may actually be more recent than our new item, if it came from another session. Insert all new items at the given index with an earlier timestamp. */ for (; new_item_iter != new_items.end(); ++new_item_iter) { if (new_item_iter->timestamp() < old_item.timestamp()) { /* This "new item" is in fact older. */ lru.add_item(*new_item_iter); } else { /* The new item is not older. */ break; } } /* Now add this old item */ lru.add_item(old_item); } munmap((void *)local_mmap_start, local_mmap_size); } /* Insert any remaining new items */ for (; new_item_iter != new_items.end(); ++new_item_iter) { lru.add_item(*new_item_iter); } signal_block(); FILE *out; if( (out=wfopen( tmp_name, "w" ) ) ) { /* Write them out */ for (history_lru_cache_t::iterator iter = lru.begin(); iter != lru.end(); ++iter) { const history_lru_node_t *node = *iter; if (! node->write_yaml_to_file(out)) { ok = false; break; } } if( fclose( out ) || !ok ) { /* This message does not have high enough priority to be shown by default. */ debug( 2, L"Error when writing history file" ); } else { wcstring new_name = history_filename(name, wcstring()); wrename(tmp_name, new_name); } } signal_unblock(); /* Make sure we clear all nodes, since this doesn't happen automatically */ lru.evict_all_nodes(); /* We've saved everything, so we have no more unsaved items */ unsaved_item_count = 0; } if( ok ) { /* Our history has been written to the file, so clear our state so we can re-reference the file. */ this->clear_file_state(); } }