From 0876c5271d999f76f864821c2082ad4b0187aeba Mon Sep 17 00:00:00 2001 From: Sanel Zukan Date: Fri, 14 Sep 2007 12:31:03 +0000 Subject: [PATCH] Recognize return codes and display appropriate dialog. Works only if executable was not found or file is not executable. Add mutexes since childs return codes comes from second thread. This will also prevent races when report dialogs are shown. --- evoke/EvokeService.cpp | 28 +++++++++++++++++++++++++--- evoke/EvokeService.h | 18 ++++++++++++++++++ evoke/Spawn.cpp | 4 +++- evoke/Splash.cpp | 4 +++- evoke/evoke.conf | 1 + 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/evoke/EvokeService.cpp b/evoke/EvokeService.cpp index b849a6c..041d2cd 100644 --- a/evoke/EvokeService.cpp +++ b/evoke/EvokeService.cpp @@ -29,6 +29,8 @@ #include #include +#include + #include // getpid #include // #include // free @@ -448,13 +450,22 @@ void EvokeService::quit_x11(void) { * Monitor starting service and report if staring * failed. Also if one of runned services crashed * attach gdb on it pid and run backtrace. + * + * FIXME: this function probably needs mutex locking; find_and_unregister_process() + * and unregister_process() are good candidates for it */ void EvokeService::service_watcher(int pid, int signum) { printf("got %i\n", signum); + Mutex mutex; + if(signum == SPAWN_CHILD_CRASHED) { EvokeProcess pc; - if(find_and_unregister_process(pid, pc)) { + mutex.lock(); + bool ret = find_and_unregister_process(pid, pc); + mutex.unlock(); + + if(ret) { printf("%s crashed with core dump\n", pc.cmd.c_str()); CrashDialog cdialog; @@ -464,11 +475,17 @@ void EvokeService::service_watcher(int pid, int signum) { } } else if(signum == SPAWN_CHILD_KILLED) { printf("child %i killed\n", pid); + } else if(signum == 127) { + edelib::alert(_("Program not found")); + } else if(signum == 126) { + edelib::alert(_("Program not executable")); } else { - printf("child %i exited with %i \n", pid, signum); + printf("child %i exited with %i\n", pid, signum); } + mutex.lock(); unregister_process(pid); + mutex.unlock(); } /* @@ -499,8 +516,13 @@ void EvokeService::run_program(const char* cmd, bool enable_vars) { if(r != 0) edelib::alert("Unable to start %s. Got code %i", cmd, r); - else + else { + Mutex mutex; + + mutex.lock(); register_process(scmd.c_str(), child); + mutex.unlock(); + } } #if 0 diff --git a/evoke/EvokeService.h b/evoke/EvokeService.h index a1277c6..1e4f4e3 100644 --- a/evoke/EvokeService.h +++ b/evoke/EvokeService.h @@ -18,6 +18,8 @@ #include #include +#include + struct EvokeClient { edelib::String desc; // short program description (used in Starting... message) edelib::String icon; // icon for this client @@ -90,4 +92,20 @@ class EvokeService { #define EVOKE_LOG EvokeService::instance()->log()->printf +/* + * FIXME: This should be probably declared somewhere outside + * or in edelib as separate class + */ +class Mutex { + private: + pthread_mutex_t mutex; + Mutex(const Mutex&); + Mutex& operator=(const Mutex&); + public: + Mutex() { pthread_mutex_init(&mutex, 0); } + ~Mutex() { pthread_mutex_destroy(&mutex); } + void lock(void) { pthread_mutex_lock(&mutex); } + void unlock(void) { pthread_mutex_unlock(&mutex); } +}; + #endif diff --git a/evoke/Spawn.cpp b/evoke/Spawn.cpp index bd72898..20d5b8b 100644 --- a/evoke/Spawn.cpp +++ b/evoke/Spawn.cpp @@ -33,9 +33,12 @@ void sigchld_handler(int sig) { int pid, status; do { errno = 0; + //pid = waitpid(WAIT_ANY, &status, WNOHANG | WUNTRACED); pid = waitpid(WAIT_ANY, &status, WNOHANG); if(global_watch != 0) { + printf("==> sigchld_handler() got %i\n", status); + if(WIFEXITED(status)) status = WEXITSTATUS(status); else if(WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) @@ -60,7 +63,6 @@ int spawn_program(const char* cmd, SignalWatch wf, pid_t* child_pid_ret, const c struct sigaction sa; sa.sa_handler = sigchld_handler; sa.sa_flags = SA_NOCLDSTOP; - //sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGCHLD, &sa, (struct sigaction*)0); diff --git a/evoke/Splash.cpp b/evoke/Splash.cpp index 26bf1ec..a707a0c 100644 --- a/evoke/Splash.cpp +++ b/evoke/Splash.cpp @@ -197,8 +197,10 @@ void Splash::run(void) { EvokeService::instance()->unregister_top(); - if(edelib::SoundSystem::inited()) + if(edelib::SoundSystem::inited()) { + edelib::SoundSystem::stop(); edelib::SoundSystem::shutdown(); + } } // called when splash option is on diff --git a/evoke/evoke.conf b/evoke/evoke.conf index b4b744e..b631566 100644 --- a/evoke/evoke.conf +++ b/evoke/evoke.conf @@ -6,6 +6,7 @@ #ImagesDirectory = /home/sanel/blentavo/EDE/ede2/evoke/images Splash = splash-alpha1.png Sound = startup.ogg +# Sound = Startup1_2.ogg [edewm] Icon = edewm.png