*/
static int open_next_audio_file(void)
{
- struct audio_file_data afd;
- int ret, shmid;
+ int ret, shmid, fd;
char buf[8];
- ret = open_and_update_audio_file(&afd);
+ ret = open_and_update_audio_file(&fd);
if (ret < 0) {
if (ret != -OSL_ERRNO_TO_PARA_ERROR(E_OSL_RB_KEY_NOT_FOUND))
PARA_ERROR_LOG("%s\n", para_strerror(-ret));
}
*(uint32_t *)buf = NEXT_AUDIO_FILE;
*(uint32_t *)(buf + 4) = (uint32_t)shmid;
- ret = pass_afd(afd.fd, buf, 8);
- close(afd.fd);
+ ret = pass_afd(fd, buf, 8);
+ close(fd);
if (ret >= 0)
return ret;
destroy:
void aft_init(struct afs_table *t);
int aft_get_row_of_path(const char *path, struct osl_row **row);
int aft_check_attributes(uint64_t att_mask, struct para_buffer *pb);
-int open_and_update_audio_file(struct audio_file_data *afd);
+int open_and_update_audio_file(int *fd);
int load_afd(int shmid, struct audio_file_data *afd);
int get_afsi_of_row(const struct osl_row *row, struct afs_info *afsi);
int get_afhi_of_row(const struct osl_row *row, struct afh_info *afhi);
/**
* Open the audio file with highest score and set up an afd structure.
*
- * \param afd Result pointer.
+ * This determines and opens the next audio file, verifies that it did not
+ * change by comparing the recomputed the hash value of the file contents
+ * against the value stored in the audio file table. If all goes well, it
+ * creates a shared memory area containing the serialized version of the afd
+ * structure, including the chunk table, if any. The caller can then send the
+ * ID of this area and the open fd to the server process.
+ *
+ * \param fd Result pointer for the file descriptor of the audio file.
*
* On success, the numplayed field of the audio file selector info is increased
* and the lastplayed time is set to the current time. Finally, the score of
*
* \return Positive shmid on success, negative on errors.
*/
-int open_and_update_audio_file(struct audio_file_data *afd)
+int open_and_update_audio_file(int *fd)
{
unsigned char file_hash[HASH_SIZE];
struct osl_object afsi_obj;
struct osl_object map, chunk_table_obj;
struct ls_data *d = &status_item_ls_data;
unsigned char *tmp_hash;
+ struct audio_file_data afd;
again:
ret = score_get_best(¤t_aft_row, &d->score);
if (ret < 0)
ret = load_afsi(&d->afsi, &afsi_obj);
if (ret < 0)
return ret;
- ret = get_afhi_of_row(current_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;
+ 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) {
} else {
PARA_INFO_LOG("chunk table: %zu bytes\n", chunk_table_obj.size);
}
- 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, fd);
if (ret < 0)
goto out;
hash_function(map.data, map.size, file_hash);
new_afsi.last_played = time(NULL);
save_afsi(&new_afsi, &afsi_obj); /* in-place update */
- afd->audio_format_id = d->afsi.audio_format_id;
- load_chunk_table(&afd->afhi, &chunk_table_obj);
+ afd.audio_format_id = d->afsi.audio_format_id;
+ load_chunk_table(&afd.afhi, &chunk_table_obj);
aced.aft_row = current_aft_row;
aced.old_afsi = &d->afsi;
/*
ret = afs_event(AFSI_CHANGE, NULL, &aced);
if (ret < 0)
goto out;
- ret = save_afd(afd);
+ ret = save_afd(&afd);
out:
- free(afd->afhi.chunk_table);
+ free(afd.afhi.chunk_table);
if (chunk_table_obj.data)
osl_close_disk_object(&chunk_table_obj);
if (ret < 0) {