Exemplo n.º 1
0
static void add_to_queue(struct SpawnRequest_t *req) {
    ASSERT_IS_LOCKED(s_spawn_queue_lock);
    s_request_queue.push(req);
}
Exemplo n.º 2
0
/** 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();
	}
}