diff options
-rw-r--r-- | src/directory.c | 1 | ||||
-rw-r--r-- | src/main.c | 78 | ||||
-rw-r--r-- | src/player.c | 89 | ||||
-rw-r--r-- | src/player.h | 2 | ||||
-rw-r--r-- | src/playerData.c | 19 | ||||
-rw-r--r-- | src/playerData.h | 3 | ||||
-rw-r--r-- | src/sig_handlers.c | 91 | ||||
-rw-r--r-- | src/sig_handlers.h | 4 |
8 files changed, 74 insertions, 213 deletions
diff --git a/src/directory.c b/src/directory.c index da4b0a4eb..9b90418f2 100644 --- a/src/directory.c +++ b/src/directory.c @@ -173,6 +173,7 @@ int updateInit(int fd, List * pathList) if (directory_updatePid == 0) { /* child */ int dbUpdated = 0; + clearPlayerPid(); unblockSignals(); diff --git a/src/main.c b/src/main.c index cf34eb989..30324cea2 100644 --- a/src/main.c +++ b/src/main.c @@ -60,9 +60,6 @@ #define SYSTEM_CONFIG_FILE_LOCATION "/etc/mpd.conf" #define USER_CONFIG_FILE_LOCATION "/.mpdconf" -volatile int masterPid = 0; -volatile int mainPid = 0; - typedef struct _Options { int kill; int daemon; @@ -312,47 +309,6 @@ static void openDB(Options * options, char *argv0) } } -static void startMainProcess(void) -{ - int pid; - fflush(0); - pid = fork(); - if (pid > 0) { - initInputStream(); - initReplayGainState(); - - /* free stuff we don't need */ - freeAllListenSockets(); - - mainPid = pid; - masterInitSigHandlers(); - kill(mainPid, SIGUSR1); - while (masterHandlePendingSignals() != COMMAND_RETURN_KILL) - waitOnSignals(); - /* we're killed */ - playerKill(); - - finishPlaylist(); - - finishAudioConfig(); - finishAudioDriver(); - - finishPaths(); - - kill(mainPid, SIGTERM); - waitpid(mainPid, NULL, 0); - finishConf(); - close_log_files(); - exit(EXIT_SUCCESS); - - } else if (pid < 0) { - ERROR("problems fork'ing main process!\n"); - exit(EXIT_FAILURE); - } - - DEBUG("main process started!\n"); -} - static void daemonize(Options * options) { FILE *fp = NULL; @@ -410,7 +366,6 @@ static void daemonize(Options * options) DEBUG("writing pid file\n"); fprintf(fp, "%lu\n", (unsigned long)getpid()); fclose(fp); - masterPid = getpid(); } } @@ -481,35 +436,30 @@ int main(int argc, char *argv[]) open_log_files(options.stdOutput); - initPlayerData(); - - initInputPlugins(); initPaths(); + initPermissions(); + initPlaylist(); + initInputPlugins(); + + openDB(&options, argv[0]); + + initCommands(); + initPlayerData(); initAudioConfig(); initAudioDriver(); + initVolume(); + initInterfaces(); + initReplayGainState(); initNormalization(); - initPlaylist(); - openDB(&options, argv[0]); + initInputStream(); daemonize(&options); - initSigHandlers(); setup_log_output(options.stdOutput); - startMainProcess(); - /* This is the main process which has - * been forked from the master process. - */ - initPermissions(); - initCommands(); - initVolume(); - initInterfaces(); - /* wait for the master process to get ready so we can start - * playing if readPlaylistState thinks we should*/ - while (COMMAND_MASTER_READY != handlePendingSignals()) - my_usleep(1); + initSigHandlers(); openVolumeDevice(); read_state_file(); @@ -523,7 +473,7 @@ int main(int argc, char *argv[]) } write_state_file(); - + playerKill(); freeAllInterfaces(); closeAllListenSockets(); diff --git a/src/player.c b/src/player.c index 7353debcf..17ec780ed 100644 --- a/src/player.c +++ b/src/player.c @@ -44,7 +44,12 @@ #include <errno.h> #include <fcntl.h> -extern int masterPid; +volatile int player_pid = 0; + +void clearPlayerPid() +{ + player_pid = 0; +} static void resetPlayerMetadata() { @@ -59,7 +64,7 @@ void resetPlayer() { int pid; - setPlayerPid(0); + clearPlayerPid(); getPlayerData()->playerControl.stop = 0; getPlayerData()->playerControl.play = 0; getPlayerData()->playerControl.pause = 0; @@ -78,17 +83,23 @@ void resetPlayer() void player_sigChldHandler(int pid, int status) { - if (getPlayerPid() == pid) { + if (player_pid == pid) + { DEBUG("SIGCHLD caused by player process\n"); - if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM && - WTERMSIG(status) != SIGINT) { + if (WIFSIGNALED(status) && + WTERMSIG(status) != SIGTERM && + WTERMSIG(status) != SIGINT) + { ERROR("player process died from signal: %i\n", WTERMSIG(status)); } resetPlayer(); - } else if (pid == getPlayerData()->playerControl.decode_pid - && getPlayerPid() <= 0) { - if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM) { + } + else if (pid == getPlayerData()->playerControl.decode_pid && + player_pid <= 0) + { + if (WIFSIGNALED(status) && WTERMSIG(status) != SIGTERM) + { ERROR("(caught by master parent) " "decode process died from a " "non-TERM signal: %i\n", WTERMSIG(status)); @@ -99,25 +110,29 @@ void player_sigChldHandler(int pid, int status) int playerInit() { - kill(masterPid, SIGUSR2); - /* we need to wait for the signal to take effect: */ - while (getPlayerPid() == 0) - my_usleep(10000); - return 0; -} - -int playerInitReal() -{ - int player_pid; blockSignals(); player_pid = fork(); - if (player_pid == 0) { + if (player_pid==0) + { + clock_t start = clock(); + PlayerControl *pc = &(getPlayerData()->playerControl); unblockSignals(); setSigHandlersForDecoder(); + closeAllListenSockets(); + freeAllInterfaces(); + closeMp3Directory(); + finishPlaylist(); + finishPermissions(); + finishCommands(); + finishVolume(); + + DEBUG("took %f to init player\n", + (float)(clock()-start)/CLOCKS_PER_SEC); + while (1) { if (pc->play) decode(); @@ -143,14 +158,14 @@ int playerInitReal() } exit(EXIT_SUCCESS); - } else if (player_pid < 0) { + } + else if (player_pid < 0) + { unblockSignals(); ERROR("player Problems fork()'ing\n"); - setPlayerPid(0); player_pid = 0; return -1; - } else - setPlayerPid(player_pid); + } unblockSignals(); @@ -174,13 +189,13 @@ int playerPlay(int fd, Song * song) pathcpy_trunc(pc->utf8url, getSongUrl(song)); pc->play = 1; - if (getPlayerPid() == 0 && playerInit() < 0) { + if (player_pid == 0 && playerInit() < 0) { pc->play = 0; return -1; } resetPlayerMetadata(); - while (getPlayerPid() > 0 && pc->play) + while (player_pid > 0 && pc->play) my_usleep(1000); return 0; @@ -190,9 +205,9 @@ int playerStop(int fd) { PlayerControl *pc = &(getPlayerData()->playerControl); - if (getPlayerPid() > 0 && pc->state != PLAYER_STATE_STOP) { + if (player_pid > 0 && pc->state != PLAYER_STATE_STOP) { pc->stop = 1; - while (getPlayerPid() > 0 && pc->stop) + while (player_pid > 0 && pc->stop) my_usleep(1000); } @@ -211,7 +226,7 @@ void playerKill() playerCloseAudio(stderr); if(player_pid>0 && pc->closeAudio) sleep(1); */ - pid = getPlayerPid(); + pid = player_pid; if (pid > 0) kill(pid, SIGTERM); } @@ -220,9 +235,9 @@ int playerPause(int fd) { PlayerControl *pc = &(getPlayerData()->playerControl); - if (getPlayerPid() > 0 && pc->state != PLAYER_STATE_STOP) { + if (player_pid > 0 && pc->state != PLAYER_STATE_STOP) { pc->pause = 1; - while (getPlayerPid() > 0 && pc->pause) + while (player_pid > 0 && pc->pause) my_usleep(1000); } @@ -233,7 +248,7 @@ int playerSetPause(int fd, int pause) { PlayerControl *pc = &(getPlayerData()->playerControl); - if (getPlayerPid() <= 0) + if (player_pid <= 0) return 0; switch (pc->state) { @@ -325,7 +340,7 @@ void playerCloseAudio() { PlayerControl *pc = &(getPlayerData()->playerControl); - if (getPlayerPid() > 0) { + if (player_pid > 0) { if (playerStop(STDERR_FILENO) < 0) return; pc->closeAudio = 1; @@ -371,9 +386,9 @@ void playerQueueLock() { PlayerControl *pc = &(getPlayerData()->playerControl); - if (getPlayerPid() > 0 && pc->queueLockState == PLAYER_QUEUE_UNLOCKED) { + if (player_pid > 0 && pc->queueLockState == PLAYER_QUEUE_UNLOCKED) { pc->lockQueue = 1; - while (getPlayerPid() > 0 && pc->lockQueue) + while (player_pid > 0 && pc->lockQueue) my_usleep(1000); } } @@ -382,9 +397,9 @@ void playerQueueUnlock() { PlayerControl *pc = &(getPlayerData()->playerControl); - if (getPlayerPid() > 0 && pc->queueLockState == PLAYER_QUEUE_LOCKED) { + if (player_pid > 0 && pc->queueLockState == PLAYER_QUEUE_LOCKED) { pc->unlockQueue = 1; - while (getPlayerPid() > 0 && pc->unlockQueue) + while (player_pid > 0 && pc->unlockQueue) my_usleep(1000); } } @@ -414,7 +429,7 @@ int playerSeek(int fd, Song * song, float time) resetPlayerMetadata(); pc->seekWhere = time; pc->seek = 1; - while (getPlayerPid() > 0 && pc->seek) + while (player_pid > 0 && pc->seek) my_usleep(1000); } diff --git a/src/player.h b/src/player.h index 77d16174b..ac83c9ea5 100644 --- a/src/player.h +++ b/src/player.h @@ -89,8 +89,6 @@ typedef struct _PlayerControl { MetadataChunk fileMetadataChunk; } PlayerControl; -int playerInitReal(); - void player_sigChldHandler(int pid, int status); int playerPlay(int fd, Song * song); diff --git a/src/playerData.c b/src/playerData.c index 79663f00f..df928acc4 100644 --- a/src/playerData.c +++ b/src/playerData.c @@ -95,15 +95,18 @@ void initPlayerData(void) /* for audioDeviceStates[] */ allocationSize += device_array_size; - if ((shmid = shmget(IPC_PRIVATE, allocationSize, IPC_CREAT | 0600)) < 0) { + if ((shmid = shmget(IPC_PRIVATE, allocationSize, IPC_CREAT | 0600)) < 0) + { ERROR("problems shmget'ing\n"); exit(EXIT_FAILURE); } - if (!(playerData_pd = shmat(shmid, NULL, 0))) { + if (!(playerData_pd = shmat(shmid, NULL, 0))) + { ERROR("problems shmat'ing\n"); exit(EXIT_FAILURE); } - if (shmctl(shmid, IPC_RMID, NULL) < 0) { + if (shmctl(shmid, IPC_RMID, NULL) < 0) + { ERROR("problems shmctl'ing\n"); exit(EXIT_FAILURE); } @@ -159,16 +162,6 @@ PlayerData *getPlayerData(void) return playerData_pd; } -int getPlayerPid(void) -{ - return playerData_pd->pid; -} - -void setPlayerPid(int pid) -{ - playerData_pd->pid = pid; -} - void freePlayerData(void) { shmdt(playerData_pd); diff --git a/src/playerData.h b/src/playerData.h index 777232bfa..00ba66d02 100644 --- a/src/playerData.h +++ b/src/playerData.h @@ -38,14 +38,11 @@ typedef struct _PlayerData { PlayerControl playerControl; DecoderControl decoderControl; mpd_uint8 *audioDeviceStates; - int pid; } PlayerData; void initPlayerData(); PlayerData *getPlayerData(); -int getPlayerPid(); -void setPlayerPid(int pid); void freePlayerData(); diff --git a/src/sig_handlers.c b/src/sig_handlers.c index e5d300778..2c6a07a00 100644 --- a/src/sig_handlers.c +++ b/src/sig_handlers.c @@ -39,34 +39,8 @@ extern volatile int masterPid; extern volatile int mainPid; -int masterHandlePendingSignals() -{ - if (signal_is_pending(SIGINT) || signal_is_pending(SIGTERM)) { - DEBUG("master process got SIGINT or SIGTERM, exiting\n"); - return COMMAND_RETURN_KILL; - } - - if (signal_is_pending(SIGHUP)) { - signal_clear(SIGHUP); - /* Forward it to the main process, which will update the DB */ - kill(mainPid, SIGHUP); - } - - return 0; -} - int handlePendingSignals() { - /* this SIGUSR1 signal comes before the KILL signals, because there if the process is - * looping, waiting for this signal, it will not respond to the KILL signal. This might be - * better implemented by using bit-wise defines and or'ing of the COMMAND_FOO as return. - */ - if (signal_is_pending(SIGUSR1)) { - signal_clear(SIGUSR1); - DEBUG("The master process is ready to receive signals\n"); - return COMMAND_MASTER_READY; - } - if (signal_is_pending(SIGINT) || signal_is_pending(SIGTERM)) { DEBUG("main process got SIGINT or SIGTERM, exiting\n"); return COMMAND_RETURN_KILL; @@ -99,56 +73,11 @@ void chldSigHandler(int signal) else break; } - directory_sigChldHandler(pid, status); - } -} - -void masterChldSigHandler(int signal) -{ - int status; - int pid; - DEBUG("master process got SIGCHLD\n"); - while (0 != (pid = wait3(&status, WNOHANG, NULL))) { - if (pid < 0) { - if (errno == EINTR) - continue; - else - break; - } - DEBUG("PID: %d\n", pid); - if (pid == mainPid) - kill(getpid(), SIGTERM); player_sigChldHandler(pid, status); + directory_sigChldHandler(pid, status); } } -int playerInitReal(); - -void masterSigUsr2Handler(int signal) -{ - DEBUG("Master process got SIGUSR2 starting a new player process\n"); - if (getPlayerPid() <= 0) - playerInitReal(); -} - -void masterInitSigHandlers() -{ - struct sigaction sa; - - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - sa.sa_handler = SIG_IGN; - while (sigaction(SIGPIPE, &sa, NULL) < 0 && errno == EINTR) ; - sa.sa_handler = masterChldSigHandler; - while (sigaction(SIGCHLD, &sa, NULL) < 0 && errno == EINTR) ; - sa.sa_handler = masterSigUsr2Handler; - while (sigaction(SIGUSR2, &sa, NULL) < 0 && errno == EINTR) ; - signal_handle(SIGUSR1); - signal_handle(SIGINT); - signal_handle(SIGTERM); - signal_handle(SIGHUP); -} - void initSigHandlers() { struct sigaction sa; @@ -159,7 +88,6 @@ void initSigHandlers() while (sigaction(SIGPIPE, &sa, NULL) < 0 && errno == EINTR) ; sa.sa_handler = chldSigHandler; while (sigaction(SIGCHLD, &sa, NULL) < 0 && errno == EINTR) ; - signal_handle(SIGUSR2); signal_handle(SIGUSR1); signal_handle(SIGINT); signal_handle(SIGTERM); @@ -202,26 +130,11 @@ void ignoreSignals() while (sigaction(SIGPIPE, &sa, NULL) < 0 && errno == EINTR) ; while (sigaction(SIGCHLD, &sa, NULL) < 0 && errno == EINTR) ; while (sigaction(SIGUSR1, &sa, NULL) < 0 && errno == EINTR) ; - while (sigaction(SIGUSR2, &sa, NULL) < 0 && errno == EINTR) ; while (sigaction(SIGINT, &sa, NULL) < 0 && errno == EINTR) ; while (sigaction(SIGTERM, &sa, NULL) < 0 && errno == EINTR) ; while (sigaction(SIGHUP, &sa, NULL) < 0 && errno == EINTR) ; } -void waitOnSignals() -{ - sigset_t sset; - - sigfillset(&sset); - sigdelset(&sset, SIGCHLD); - sigdelset(&sset, SIGUSR1); - sigdelset(&sset, SIGUSR2); - sigdelset(&sset, SIGHUP); - sigdelset(&sset, SIGINT); - sigdelset(&sset, SIGTERM); - sigsuspend(&sset); -} - void blockSignals() { sigset_t sset; @@ -229,7 +142,6 @@ void blockSignals() sigemptyset(&sset); sigaddset(&sset, SIGCHLD); sigaddset(&sset, SIGUSR1); - sigaddset(&sset, SIGUSR2); sigaddset(&sset, SIGHUP); sigaddset(&sset, SIGINT); sigaddset(&sset, SIGTERM); @@ -243,7 +155,6 @@ void unblockSignals() sigemptyset(&sset); sigaddset(&sset, SIGCHLD); sigaddset(&sset, SIGUSR1); - sigaddset(&sset, SIGUSR2); sigaddset(&sset, SIGHUP); sigaddset(&sset, SIGINT); sigaddset(&sset, SIGTERM); diff --git a/src/sig_handlers.h b/src/sig_handlers.h index 186ebb85f..c58696d0d 100644 --- a/src/sig_handlers.h +++ b/src/sig_handlers.h @@ -22,10 +22,8 @@ #include "../config.h" int handlePendingSignals(); -int masterHandlePendingSignals(); void initSigHandlers(); -void masterInitSigHandlers(); void finishSigHandlers(); @@ -33,8 +31,6 @@ void setSigHandlersForDecoder(); void ignoreSignals(); -void waitOnSignals(); - void blockSignals(); void unblockSignals(); |