It may happen that the score table contains references to files that
no longer exist in the file system. The current code fails badly in
this case.
In open_next_audio_file(), if the file corresponding to the next
entry in the score table can not be opened, delete this entry from
the score table and try the next entry.
If the score table becomes empty, send NO_ADMISSIBLE_FILES back to para_server
and make recv_afs_result() switch to stop mode in this case.
int ret, shmid;
char buf[8];
long score;
int ret, shmid;
char buf[8];
long score;
PARA_NOTICE_LOG("getting next audio file\n");
ret = score_get_best(&aft_row, &score);
PARA_NOTICE_LOG("getting next audio file\n");
ret = score_get_best(&aft_row, &score);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ goto no_admissible_files;
+ }
ret = open_and_update_audio_file(aft_row, score, &afd);
ret = open_and_update_audio_file(aft_row, score, &afd);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ ret = score_delete(aft_row);
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ goto no_admissible_files;
+ }
+ goto again;
+ }
shmid = ret;
if (!write_ok(server_socket)) {
shmid = ret;
if (!write_ok(server_socket)) {
- PARA_EMERG_LOG("afs_socket not writable\n");
goto destroy;
}
*(uint32_t *)buf = NEXT_AUDIO_FILE;
goto destroy;
}
*(uint32_t *)buf = NEXT_AUDIO_FILE;
close(afd.fd);
if (ret >= 0)
return ret;
close(afd.fd);
if (ret >= 0)
return ret;
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
destroy:
shm_destroy(shmid);
return ret;
destroy:
shm_destroy(shmid);
return ret;
+no_admissible_files:
+ *(uint32_t *)buf = NO_ADMISSIBLE_FILES;
+ *(uint32_t *)(buf + 4) = (uint32_t)0;
+ return send_bin_buffer(server_socket, buf, 8);
}
/* Never fails if arg == NULL */
}
/* Never fails if arg == NULL */
PARA_DEBUG_LOG("received: %s\n", buf);
if (!strcmp(buf, "new")) {
ret = open_next_audio_file();
PARA_DEBUG_LOG("received: %s\n", buf);
if (!strcmp(buf, "new")) {
ret = open_next_audio_file();
- if (ret < 0)
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ if (ret < 0) {
+ PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+ unregister_tasks();
+ }
return;
}
PARA_ERROR_LOG("unknown command\n");
return;
}
PARA_ERROR_LOG("unknown command\n");
enum afs_server_code {
NEXT_AUDIO_FILE,
enum afs_server_code {
NEXT_AUDIO_FILE,
PARA_ERROR(INPUT_TOO_LARGE, "input too large for stdin command"), \
PARA_ERROR(AFS_SYNTAX, "afs syntax error"), \
PARA_ERROR(AFS_SIGNAL, "afs caught deadly signal"), \
PARA_ERROR(INPUT_TOO_LARGE, "input too large for stdin command"), \
PARA_ERROR(AFS_SYNTAX, "afs syntax error"), \
PARA_ERROR(AFS_SIGNAL, "afs caught deadly signal"), \
+ PARA_ERROR(AFS_SOCKET, "afs socket not writable"), \
PARA_ERROR(AFS_PARENT_DIED, "fatal: server process terminated"), \
PARA_ERROR(AFS_PARENT_DIED, "fatal: server process terminated"), \
PARA_ERROR(AUDIO_FORMAT, "audio format not recognized"), \
PARA_ERROR(CHUNK, "unable to get chunk"), \
PARA_ERROR(SHORT_AFS_READ, "short read from afs socket"), \
PARA_ERROR(AUDIO_FORMAT, "audio format not recognized"), \
PARA_ERROR(CHUNK, "unable to get chunk"), \
PARA_ERROR(SHORT_AFS_READ, "short read from afs socket"), \
- PARA_ERROR(BAD_AFS_CODE, "received junk from afs"), \
+ PARA_ERROR(NOFD, "did not receive open fd from afs"), \
struct iovec iov;
int ret = 0;
struct iovec iov;
int ret = 0;
iov.iov_base = buf;
iov.iov_len = sizeof(buf);
msg.msg_iov = &iov;
iov.iov_base = buf;
iov.iov_len = sizeof(buf);
msg.msg_iov = &iov;
ret = recvmsg(afs_socket, &msg, 0);
if (ret < 0)
return -ERRNO_TO_PARA_ERROR(errno);
ret = recvmsg(afs_socket, &msg, 0);
if (ret < 0)
return -ERRNO_TO_PARA_ERROR(errno);
+ afsss = AFS_SOCKET_READY;
if (iov.iov_len != sizeof(buf))
return -E_SHORT_AFS_READ;
*code = *(uint32_t*)buf;
if (iov.iov_len != sizeof(buf))
return -E_SHORT_AFS_READ;
*code = *(uint32_t*)buf;
static void recv_afs_result(void)
{
static void recv_afs_result(void)
{
- int ret, passed_fd = -1, shmid;
+ int ret, passed_fd, shmid;
uint32_t afs_code = 0, afs_data = 0;
struct stat statbuf;
struct timeval now;
uint32_t afs_code = 0, afs_data = 0;
struct stat statbuf;
struct timeval now;
ret = recv_afs_msg(&passed_fd, &afs_code, &afs_data);
if (ret < 0)
goto err;
ret = recv_afs_msg(&passed_fd, &afs_code, &afs_data);
if (ret < 0)
goto err;
- PARA_DEBUG_LOG("got the fd: %d, code: %u, shmid: %u\n",
- passed_fd, afs_code, afs_data);
- ret = -E_BAD_AFS_CODE;
+ PARA_DEBUG_LOG("fd: %d, code: %u, shmid: %u\n", passed_fd, afs_code,
+ afs_data);
+ ret = -E_NOFD;
if (afs_code != NEXT_AUDIO_FILE)
goto err;
if (afs_code != NEXT_AUDIO_FILE)
goto err;
- afsss = AFS_SOCKET_READY;
+ if (passed_fd < 0)
+ goto err;
shmid = afs_data;
ret = load_afd(shmid, &mmd->afd);
if (ret < 0)
shmid = afs_data;
ret = load_afd(shmid, &mmd->afd);
if (ret < 0)
if (passed_fd >= 0)
close(passed_fd);
PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
if (passed_fd >= 0)
close(passed_fd);
PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ mmd->new_vss_status_flags = VSS_NEXT;
}
void vss_post_select(fd_set *rfds, fd_set *wfds)
}
void vss_post_select(fd_set *rfds, fd_set *wfds)