From 2176cbf10d8f3815f0a17bcc35e4d2e79440d26c Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 5 Sep 2021 22:38:41 +0200 Subject: [PATCH] Remove ->fd of struct audio file data. This structure contains information about the next audio file. It is stored in a shared memory area, and a reference to this area is sent through a pipe from the afs process to the server process. The file descriptor of the next audio file, however, must be passed via Unix socket magic (SCM_RIGHTS) and thus does not need to be part of the structure. Moreover, it's easier to define the afd structure in open_and_update_audio_file() of aft.c rather than in its caller, open_next_audio_file() of afs.c, because the caller only needs the fd of the audio file and the shared memory ID but not the audio file data structure itself. Expand the documentation of open_and_update_audio_file() a bit while at it. --- afh.h | 2 -- afs.c | 9 ++++----- afs.h | 2 +- aft.c | 28 ++++++++++++++++++---------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/afh.h b/afh.h index 881db3c2..b3295f6e 100644 --- a/afh.h +++ b/afh.h @@ -58,8 +58,6 @@ struct afh_info { /** Data about the current audio file, passed from afs to server. */ struct audio_file_data { - /** The open file descriptor to the current audio file. */ - int fd; /** Vss needs this for streaming. */ struct afh_info afhi; /** diff --git a/afs.c b/afs.c index 050e1965..b6cce36f 100644 --- a/afs.c +++ b/afs.c @@ -418,11 +418,10 @@ static int pass_afd(int fd, char *buf, size_t size) */ 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)); @@ -435,8 +434,8 @@ static int open_next_audio_file(void) } *(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: diff --git a/afs.h b/afs.h index cfa9cc6d..b1606493 100644 --- a/afs.h +++ b/afs.h @@ -255,7 +255,7 @@ int attribute_check_callback(struct afs_callback_arg *aca); 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); diff --git a/aft.c b/aft.c index b358c96c..c8c98e7a 100644 --- a/aft.c +++ b/aft.c @@ -1024,7 +1024,14 @@ out: /** * 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 @@ -1032,7 +1039,7 @@ out: * * \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; @@ -1042,6 +1049,7 @@ int open_and_update_audio_file(struct audio_file_data *afd) 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) @@ -1074,11 +1082,11 @@ again: 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) { @@ -1090,7 +1098,7 @@ again: } 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); @@ -1105,8 +1113,8 @@ again: 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; /* @@ -1116,9 +1124,9 @@ again: 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) { -- 2.39.5