From 4b00c62587dbe0ce131992dcd574ffe323cffa5c Mon Sep 17 00:00:00 2001 From: Qball Cow Date: Fri, 18 Nov 2005 12:09:05 +0000 Subject: DJWLindenaar's fix race condition and some memory leaks patch git-svn-id: https://svn.musicpd.org/mpd/trunk@3681 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/command.h | 1 + src/conf.c | 5 +++++ src/conf.h | 1 + src/main.c | 24 +++++++++++++++++------- src/myfprintf.c | 7 +++++++ src/myfprintf.h | 1 + src/sig_handlers.c | 13 ++++++++++++- 7 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/command.h b/src/command.h index cf8874a17..edf42aa81 100644 --- a/src/command.h +++ b/src/command.h @@ -30,6 +30,7 @@ #define COMMAND_RETURN_KILL 10 #define COMMAND_RETURN_CLOSE 20 +#define COMMAND_MASTER_READY 30 extern char * current_command; extern int command_listNum; diff --git a/src/conf.c b/src/conf.c index 9675e97d3..53c2370f3 100644 --- a/src/conf.c +++ b/src/conf.c @@ -112,6 +112,10 @@ void registerConfigParam(char * name, int repeatable, int block) { insertInList(configEntriesList, name, entry); } +void finishConf() { + freeList(configEntriesList); +} + void initConf() { configEntriesList = makeList((ListFreeDataFunc *)freeConfigEntry, 1); @@ -295,6 +299,7 @@ void readConf(char * file) { freeArgArray(array, numberOfArgs); } + fclose(fp); } ConfigParam * getNextConfigParam(char * name, ConfigParam * last) { diff --git a/src/conf.h b/src/conf.h index 375752b53..ce48e640f 100644 --- a/src/conf.h +++ b/src/conf.h @@ -73,6 +73,7 @@ typedef struct _ConfigParam { } ConfigParam; void initConf(); +void finishConf(); void readConf(char * file); diff --git a/src/main.c b/src/main.c index 4c6ef9c26..1866ecfe0 100644 --- a/src/main.c +++ b/src/main.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -306,6 +307,7 @@ void startMainProcess() { mainPid = pid; masterInitSigHandlers(); + kill(mainPid, SIGUSR1); while (masterHandlePendingSignals()!=COMMAND_RETURN_KILL) waitOnSignals(); /* we're killed */ @@ -320,6 +322,9 @@ void startMainProcess() { finishPaths(); kill(mainPid, SIGTERM); + waitpid(mainPid,NULL,0); + finishConf(); + myfprintfCloseLogFile(); exit(EXIT_SUCCESS); } else if(pid<0) { @@ -483,8 +488,8 @@ void killFromPidFile(char * cmd, int killOption) { } int main(int argc, char * argv[]) { - FILE * out; - FILE * err; + FILE * out = NULL; + FILE * err = NULL; Options options; closeAllFDs(); @@ -519,8 +524,7 @@ int main(int argc, char * argv[]) { /* This is the main process which has * been forked from the master process. */ - - + initSigHandlers(); initPermissions(); @@ -539,8 +543,12 @@ int main(int argc, char * argv[]) { setupLogOutput(&options, out, err); - openVolumeDevice(); - initSigHandlers(); + /* 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); + + openVolumeDevice(); readPlaylistState(); @@ -567,6 +575,8 @@ int main(int argc, char * argv[]) { finishCommands(); finishInputPlugins(); cleanUpPidFile(); - + finishConf(); + + myfprintfCloseLogFile(); return EXIT_SUCCESS; } diff --git a/src/myfprintf.c b/src/myfprintf.c index a959b6609..c333e9c7f 100644 --- a/src/myfprintf.c +++ b/src/myfprintf.c @@ -122,3 +122,10 @@ int myfprintfCloseAndOpenLogFile() { return 0; } + +void myfprintfCloseLogFile() { + if(myfprintf_stdLogMode) { + while(fclose(myfprintf_out)<0 && errno==EINTR); + while(fclose(myfprintf_err)<0 && errno==EINTR); + } +} diff --git a/src/myfprintf.h b/src/myfprintf.h index 4ffe9725a..45eaf9289 100644 --- a/src/myfprintf.h +++ b/src/myfprintf.h @@ -29,4 +29,5 @@ void myfprintf(FILE * fp, char * format, ... ); int myfprintfCloseAndOpenLogFile(); +void myfprintfCloseLogFile(); #endif diff --git a/src/sig_handlers.c b/src/sig_handlers.c index 364636e7c..567a39133 100644 --- a/src/sig_handlers.c +++ b/src/sig_handlers.c @@ -56,7 +56,17 @@ int masterHandlePendingSignals() { } int handlePendingSignals() { - if(signal_is_pending(SIGINT) || signal_is_pending(SIGTERM)) { + /* 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; } @@ -135,6 +145,7 @@ 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); -- cgit v1.2.3