/** * 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 ); }
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(); }
/* 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); }
/* 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); }
/* 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); }
/** * 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; }
/* 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 ); }
/* * 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); }
/** * 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()))); } }