Пример #1
0
/**
 * Remove all the children of a node and removes the node
 *
 * \param p_playlist the playlist
 * \param p_root the node
 * \param b_delete_items do we have to delete the children items ?
 * \return VLC_SUCCESS or an error
 */
int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
                         bool b_delete_items, bool b_force )
{
    PL_ASSERT_LOCKED;

    /* Delete the children */
    for( int i = p_root->i_children - 1 ; i >= 0; i-- )
        if( b_delete_items || p_root->pp_children[i]->i_children >= 0 )
            playlist_NodeDelete( p_playlist, p_root->pp_children[i],
                                 b_delete_items, b_force );

    /* Delete the node */
    if( p_root->i_flags & PLAYLIST_RO_FLAG && !b_force )
        return VLC_SUCCESS;

    pl_priv(p_playlist)->b_reset_currently_playing = true;

    int i;
    var_SetInteger( p_playlist, "playlist-item-deleted", p_root->i_id );
    ARRAY_BSEARCH( p_playlist->all_items, ->i_id, int, p_root->i_id, i );
    if( i != -1 )
        ARRAY_REMOVE( p_playlist->all_items, i );

    if( p_root->i_children == -1 ) {
        ARRAY_BSEARCH( p_playlist->items,->i_id, int, p_root->i_id, i );
        if( i != -1 )
            ARRAY_REMOVE( p_playlist->items, i );
    }
Пример #2
0
void vlc_event_detach( vlc_event_manager_t *p_em,
                       vlc_event_type_t event_type,
                       vlc_event_callback_t pf_callback,
                       void *p_user_data )
{
    vlc_event_listeners_group_t *slot = &p_em->events[event_type];

    vlc_mutex_lock( &p_em->lock );

    for (int i = 0; i < slot->listeners.i_size; ++i)
    {
        struct vlc_event_listener_t *listener = slot->listeners.p_elems[i];
        if( listener->pf_callback == pf_callback &&
            listener->p_user_data == p_user_data )
        {
            /* that's our listener */
            ARRAY_REMOVE( slot->listeners, i );
            vlc_mutex_unlock( &p_em->lock );
            free( listener );
            return;
        }
    }

    vlc_assert_unreachable();
}
Пример #3
0
/* Body state. */
int
imap_state_body(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;
	struct mail		*m = fctx->mail;
	struct fetch_imap_mail	*aux;
	char			*line, *ptr;
	u_int			 n;

	if (imap_getln(a, fctx, IMAP_UNTAGGED, &line) != 0)
		return (FETCH_ERROR);
	if (line == NULL)
		return (FETCH_BLOCK);

	if (sscanf(line, "* %u FETCH (", &n) != 1)
		return (imap_invalid(a, line));
	if ((ptr = strstr(line, "BODY[] {")) == NULL)
		return (imap_invalid(a, line));

	if (sscanf(ptr, "BODY[] {%zu}", &data->size) != 1)
		return (imap_invalid(a, line));
	data->lines = 0;

	/* Fill in local data. */
	aux = xcalloc(1, sizeof *aux);
	aux->uid = ARRAY_FIRST(&data->wanted);
	m->auxdata = aux;
	m->auxfree = imap_free;
	ARRAY_REMOVE(&data->wanted, 0);

	/* Open the mail. */
	if (mail_open(m, data->size) != 0) {
		log_warnx("%s: failed to create mail", a->name);
		return (FETCH_ERROR);
	}
	m->size = 0;

	/* Tag mail. */
	default_tags(&m->tags, data->src);
	if (data->server.host != NULL) {
		add_tag(&m->tags, "server", "%s", data->server.host);
		add_tag(&m->tags, "port", "%s", data->server.port);
	}
	add_tag(&m->tags, "server_uid", "%u", aux->uid);
	add_tag(&m->tags,
	    "folder", "%s", ARRAY_ITEM(data->folders, data->folder));

	/* If we already know the mail is oversize, start off flushing it. */
	data->flushing = data->size > conf.max_size;

	fctx->state = imap_state_line;
	return (FETCH_AGAIN);
}
Пример #4
0
/* Free an item by index. */
int
paste_free_index(struct paste_stack *ps, u_int idx)
{
	struct paste_buffer	*pb;

	if (idx >= ARRAY_LENGTH(ps))
		return (-1);

	pb = ARRAY_ITEM(ps, idx);
	ARRAY_REMOVE(ps, idx);

	xfree(pb->data);
	xfree(pb);

	return (0);
}
Пример #5
0
/* Free the top item on the stack. */
int
paste_free_top(struct paste_stack *ps)
{
	struct paste_buffer	*pb;

	if (ARRAY_LENGTH(ps) == 0)
		return (-1);

	pb = ARRAY_FIRST(ps);
	ARRAY_REMOVE(ps, 0);

	xfree(pb->data);
	xfree(pb);

	return (0);
}
Пример #6
0
/**
 * Remove all the children of a node and removes the node
 *
 * \param p_playlist the playlist
 * \param p_root the node
 * \param b_delete_items do we have to delete the children items ?
 * \return VLC_SUCCESS or an error
 */
int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
                         bool b_delete_items, bool b_force )
{
    PL_ASSERT_LOCKED;
    int i;

    if( p_root->i_children == -1 )
    {
        return VLC_EGENERIC;
    }

    /* Delete the children */
    for( i =  p_root->i_children - 1 ; i >= 0; i-- )
    {
        if( p_root->pp_children[i]->i_children > -1 )
        {
            playlist_NodeDelete( p_playlist, p_root->pp_children[i],
                                 b_delete_items , b_force );
        }
        else if( b_delete_items )
        {
            playlist_DeleteFromItemId( p_playlist,
                                       p_root->pp_children[i]->i_id );
        }
    }
    /* Delete the node */
    if( p_root->i_flags & PLAYLIST_RO_FLAG && !b_force )
    {
    }
    else
    {
        int i;
        var_SetInteger( p_playlist, "playlist-item-deleted", p_root->i_id );
        ARRAY_BSEARCH( p_playlist->all_items, ->i_id, int,
                       p_root->i_id, i );
        if( i != -1 )
            ARRAY_REMOVE( p_playlist->all_items, i );

        /* Remove the item from its parent */
        if( p_root->p_parent )
            playlist_NodeRemoveItem( p_playlist, p_root, p_root->p_parent );

        playlist_ItemRelease( p_root );
    }
    return VLC_SUCCESS;
}
Пример #7
0
/* Actually convert an item to a node */
static void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item )
{
    int i;
    if( p_item->i_children != -1 ) return;

    p_item->i_children = 0;

    input_item_t *p_input = p_item->p_input;
    vlc_mutex_lock( &p_input->lock );
    p_input->i_type = ITEM_TYPE_NODE;
    vlc_mutex_unlock( &p_input->lock );

    var_SetAddress( p_playlist, "item-change", p_item->p_input );

    /* Remove it from the array of available items */
    ARRAY_BSEARCH( p_playlist->items,->i_id, int, p_item->i_id, i );
    if( i != -1 )
        ARRAY_REMOVE( p_playlist->items, i );
}
Пример #8
0
/*
 * Next state. Get next mail. This is also the idle state when completed, so
 * check for finished mail, exiting, and so on.
 */
int
imap_state_next(struct account *a, struct fetch_ctx *fctx)
{
	struct fetch_imap_data	*data = a->data;

	/* Handle dropped and kept mail. */
	if (!ARRAY_EMPTY(&data->dropped)) {
		if (imap_putln(a, "%u UID STORE %u +FLAGS.SILENT (\\Deleted)",
		    ++data->tag, ARRAY_FIRST(&data->dropped)) != 0)
			return (FETCH_ERROR);
		ARRAY_REMOVE(&data->dropped, 0);
		fctx->state = imap_state_commit;
		return (FETCH_BLOCK);
	}
	if (!ARRAY_EMPTY(&data->kept)) {
		/*
		 * GMail is broken and does not set the \Seen flag after mail
		 * is fetched, so set it explicitly for kept mail.
		 */
		if (imap_putln(a, "%u UID STORE %u +FLAGS.SILENT (\\Seen)",
		    ++data->tag, ARRAY_FIRST(&data->kept)) != 0)
			return (FETCH_ERROR);
		ARRAY_REMOVE(&data->kept, 0);
		fctx->state = imap_state_commit;
		return (FETCH_BLOCK);
	}

	/* Need to purge, switch to purge state. */
	if (fctx->flags & FETCH_PURGE) {
		/*
		 * If can't purge now, loop through this state until there is
		 * no mail on the dropped queue and FETCH_EMPTY is set. Can't
		 * have a seperate state to loop through without returning
		 * here: mail could potentially be added to the dropped list
		 * while in that state.
		 */
		if (fctx->flags & FETCH_EMPTY) {
			fctx->flags &= ~FETCH_PURGE;

			if (imap_putln(a, "%u EXPUNGE", ++data->tag) != 0)
				return (FETCH_ERROR);
			fctx->state = imap_state_expunge;
			return (FETCH_BLOCK);
		}

		/*
		 * Must be waiting for delivery, so permit blocking even though
		 * we (fetch) aren't waiting for any data.
		 */
		return (FETCH_BLOCK);
	}

	/* If last mail, wait for everything to be committed then close down. */
	if (ARRAY_EMPTY(&data->wanted)) {
		if (data->committed != data->total)
			return (FETCH_BLOCK);
		if (imap_putln(a, "%u CLOSE", ++data->tag) != 0)
			return (FETCH_ERROR);
		fctx->state = imap_state_close;
		return (FETCH_BLOCK);
	}

	/* Fetch the next mail. */
	if (imap_putln(a, "%u "
	    "UID FETCH %u BODY[]",++data->tag, ARRAY_FIRST(&data->wanted)) != 0)
		return (FETCH_ERROR);
	fctx->state = imap_state_body;
	return (FETCH_BLOCK);
}
Пример #9
0
/**
 * Remove value from a key, discarding the association between the creator ID
 * and the 64-bit DB key.
 *
 * The keys is known to hold the value already.
 *
 * @param id		the primary key
 * @param cid		the secondary key (creator's ID)
 * @param dbkey		the 64-bit DB key (informational, for assertions)
 */
void
keys_remove_value(const kuid_t *id, const kuid_t *cid, uint64 dbkey)
{
	struct keyinfo *ki;
	struct keydata *kd;
	int idx;

	ki = hikset_lookup(keys, id);

	g_assert(ki);

	kd = get_keydata(id);
	if (NULL == kd)
		return;

	g_assert(kd->values);
	g_assert(kd->values == ki->values);
	g_assert(kd->values <= MAX_VALUES);

	idx = lookup_secondary_idx(kd, cid);

	g_assert(idx >= 0 && idx < kd->values);
	g_assert(dbkey == kd->dbkeys[idx]);

	ARRAY_REMOVE(kd->creators, idx, kd->values);
	ARRAY_REMOVE(kd->dbkeys,   idx, kd->values);
	ARRAY_REMOVE(kd->expire,   idx, kd->values);

	/*
	 * We do not synchronously delete empty keys.
	 *
	 * This lets us optimize the nominal case whereby a key loses all its
	 * values due to a STORE request causing a lifetime check.  But the
	 * STORE will precisely insert back another value.
	 *
	 * Hence lazy expiration also gives us the opportunity to further exploit
	 * caching in memory, the keyinfo being held there as a "cached" value.
	 *
	 * Reclaiming of dead keys happens during periodic key load computation.
	 */

	kd->values--;
	ki->values--;

	/*
	 * Recompute next expiration time.
	 */

	ki->next_expire = TIME_T_MAX;

	for (idx = 0; idx < ki->values; idx++) {
		ki->next_expire = MIN(ki->next_expire, kd->expire[idx]);
	}

	dbmw_write(db_keydata, id, kd, sizeof *kd);

	if (GNET_PROPERTY(dht_storage_debug) > 2) {
		g_debug("DHT STORE key %s now holds only %d/%d value%s, expire in %s",
			kuid_to_hex_string(id), ki->values, MAX_VALUES, plural(ki->values),
			compact_time(delta_time(ki->next_expire, tm_time())));
	}
}