return ret;
}
-static int make_status_items(struct ls_data *d)
+static struct ls_data status_item_ls_data;
+static struct osl_row *current_aft_row;
+
+static int make_status_items(void)
{
struct ls_options opts = {
.flags = LS_FLAG_FULL_PATH | LS_FLAG_ADMISSIBLE_ONLY,
int ret;
time(¤t_time);
- ret = print_list_item(d, &opts, &pb, current_time);
+ ret = print_list_item(&status_item_ls_data, &opts, &pb, current_time);
if (ret < 0)
return ret;
free(status_items);
memset(&pb, 0, sizeof(pb));
pb.max_size = shm_get_shmmax() - 1;
pb.flags = PBF_SIZE_PREFIX;
- ret = print_list_item(d, &opts, &pb, current_time);
+ ret = print_list_item(&status_item_ls_data, &opts, &pb, current_time);
if (ret < 0) {
free(status_items);
status_items = NULL;
*/
int open_and_update_audio_file(struct audio_file_data *afd)
{
- struct osl_row *aft_row;
unsigned char file_hash[HASH_SIZE];
struct osl_object afsi_obj;
struct afs_info new_afsi;
int ret;
struct afsi_change_event_data aced;
struct osl_object map, chunk_table_obj;
- struct ls_data d;
+ struct ls_data *d = &status_item_ls_data;
again:
- ret = score_get_best(&aft_row, &d.score);
+ ret = score_get_best(¤t_aft_row, &d->score);
if (ret < 0)
return ret;
- ret = get_hash_of_row(aft_row, &d.hash);
+ ret = get_hash_of_row(current_aft_row, &d->hash);
if (ret < 0)
return ret;
- ret = get_audio_file_path_of_row(aft_row, &d.path);
+ ret = get_audio_file_path_of_row(current_aft_row, &d->path);
if (ret < 0)
return ret;
- PARA_NOTICE_LOG("%s\n", d.path);
- ret = get_afsi_object_of_row(aft_row, &afsi_obj);
+ PARA_NOTICE_LOG("%s\n", d->path);
+ ret = get_afsi_object_of_row(current_aft_row, &afsi_obj);
if (ret < 0)
return ret;
- ret = load_afsi(&d.afsi, &afsi_obj);
+ ret = load_afsi(&d->afsi, &afsi_obj);
if (ret < 0)
return ret;
- ret = get_afhi_of_row(aft_row, &afd->afhi);
+ ret = get_afhi_of_row(current_aft_row, &afd->afhi);
if (ret < 0)
return ret;
- d.afhi = afd->afhi;
- d.afhi.chunk_table = afd->afhi.chunk_table = NULL;
- ret = osl(osl_open_disk_object(audio_file_table, aft_row,
+ d->afhi = afd->afhi;
+ d->afhi.chunk_table = afd->afhi.chunk_table = NULL;
+ ret = osl(osl_open_disk_object(audio_file_table, current_aft_row,
AFTCOL_CHUNKS, &chunk_table_obj));
if (ret < 0)
return ret;
- ret = mmap_full_file(d.path, O_RDONLY, &map.data, &map.size, &afd->fd);
+ ret = mmap_full_file(d->path, O_RDONLY, &map.data, &map.size, &afd->fd);
if (ret < 0)
goto err;
hash_function(map.data, map.size, file_hash);
- ret = hash_compare(file_hash, d.hash);
+ ret = hash_compare(file_hash, d->hash);
para_munmap(map.data, map.size);
if (ret) {
ret = -E_HASH_MISMATCH;
goto err;
}
- new_afsi = d.afsi;
+ new_afsi = d->afsi;
new_afsi.num_played++;
new_afsi.last_played = time(NULL);
save_afsi(&new_afsi, &afsi_obj); /* in-place update */
- afd->audio_format_id = d.afsi.audio_format_id;
+ afd->audio_format_id = d->afsi.audio_format_id;
load_chunk_table(&afd->afhi, chunk_table_obj.data);
- ret = make_status_items(&d);
- if (ret < 0)
- goto err;
- aced.aft_row = aft_row;
- aced.old_afsi = &d.afsi;
+ aced.aft_row = current_aft_row;
+ aced.old_afsi = &d->afsi;
+ /*
+ * No need to update the status items as the AFSI_CHANGE event will
+ * recreate them.
+ */
afs_event(AFSI_CHANGE, NULL, &aced);
ret = save_afd(afd);
err:
free(afd->afhi.chunk_table);
osl_close_disk_object(&chunk_table_obj);
if (ret < 0) {
- PARA_ERROR_LOG("%s: %s\n", d.path, para_strerror(-ret));
- ret = score_delete(aft_row);
+ PARA_ERROR_LOG("%s: %s\n", d->path, para_strerror(-ret));
+ ret = score_delete(current_aft_row);
if (ret >= 0)
goto again;
}
if (ret < 0)
return ret;
return audio_file_loop(data, clear_attribute);
- }
- default:
+ } case AFSI_CHANGE: {
+ struct afsi_change_event_data *aced = data;
+ uint64_t old_last_played = status_item_ls_data.afsi.last_played;
+ if (aced->aft_row != current_aft_row)
+ return 0;
+ ret = get_afsi_of_row(aced->aft_row, &status_item_ls_data.afsi);
+ if (ret < 0)
+ return ret;
+ status_item_ls_data.afsi.last_played = old_last_played;
+ make_status_items();
return 1;
+ } case AFHI_CHANGE: {
+ if (data != current_aft_row)
+ return 0;
+ ret = get_afhi_of_row(data, &status_item_ls_data.afhi);
+ if (ret < 0)
+ return ret;
+ make_status_items();
+ return 1;
+ } default:
+ return 0;
}
}