diff --git a/qse/include/qse/cmn/Bitset.hpp b/qse/include/qse/cmn/Bitset.hpp index 6cf4ac13..4cb656c6 100644 --- a/qse/include/qse/cmn/Bitset.hpp +++ b/qse/include/qse/cmn/Bitset.hpp @@ -32,15 +32,97 @@ QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -template +template class Bitset { public: - static const int NW = (NB - 1) / (QSE_SIZEOF(qse_size_t) * 8) + 1; + typedef qse_size_t word_type_t; + + static const int NW = (NB - 1) / (QSE_SIZEOF(word_type_t) * 8) + 1; + + Bitset() { this->empty (); } + + bool operator== (const Bitset& bs) const + { + // [NOTE] + // if you happen to have different garbage at the unused part + // of the last word, this equality check may return a wrong result. + for (int i = 0; i < NW; i++) + { + if (this->_w[i] != bs._w[i]) return false; + } + return true; + } + + bool operator!= (const Bitset& bs) const + { + return !this->operator==(bs); + } + + int get_word_index (int bit) const + { + return bit / (QSE_SIZEOF(word_type_t) * 8); + } + + word_type_t get_word_mask (int bit) const + { + return ((word_type_t)1) << (bit % (QSE_SIZEOF(word_type_t) * 8)); + } + + void set (int bit) + { + this->_w[this->get_word_index(bit)] |= this->get_word_mask(bit); + } + + void unset (int bit) + { + this->_w[this->get_word_index(bit)] &= ~this->get_word_mask(bit); + } + + void set (const Bitset& bs) + { + // mask on all bits set in bs. + for (int i = 0; i < NW; i++) + { + this->_w[i] |= bs._w[i]; + } + } + + void unset (const Bitset& bs) + { + // mask off all bits set in bs. + for (int i = 0; i < NW; i++) + { + this->_w[i] &= ~bs._w[i]; + } + } + + bool isSet (int bit) const + { + return (this->_w[this->get_word_index(bit)] & this->get_word_mask(bit)); + } + + bool isEmpty () const + { + for (int i = 0; i < NW; i++) + { + if (this->_w[i]) return false; + } + return true; + } + + void empty () + { + for (int i = 0; i < NW; i++) this->_w[i] = 0; + } + + void fill () + { + for (int i = 0; i < NW; i++) this->_w[i] = ~(word_type_t)0; + } - protected: - qse_size_t _w[NW]; + word_type_t _w[NW]; }; ///////////////////////////////// diff --git a/qse/include/qse/si/App.hpp b/qse/include/qse/si/App.hpp index cda3be54..f041b4a4 100644 --- a/qse/include/qse/si/App.hpp +++ b/qse/include/qse/si/App.hpp @@ -30,6 +30,7 @@ #include #include #include +#include ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) @@ -38,6 +39,8 @@ QSE_BEGIN_NAMESPACE(QSE) class App: public Uncopyable, public Types, public Mmged { public: + typedef QSE::Bitset Sigset; + App (Mmgr* mmgr) QSE_CPP_NOEXCEPT; virtual ~App () QSE_CPP_NOEXCEPT; @@ -70,7 +73,7 @@ public: static int setSignalHandler (int sig, SignalHandler sighr); static int unsetSignalHandler (int sig); - int guardProcess (const qse_mchar_t* proc_name); + int guardProcess (const qse_mchar_t* proc_name, const Sigset& signals); private: App* _prev_app; diff --git a/qse/lib/si/App.cpp b/qse/lib/si/App.cpp index ab764657..61a7301e 100644 --- a/qse/lib/si/App.cpp +++ b/qse/lib/si/App.cpp @@ -293,7 +293,7 @@ int App::unset_signal_handler_no_mutex(int sig) void App::on_guard_signal (int sig) { -printf ("relaying %d to %d\n", sig, this->_guarded_child_pid); +printf ("relaying %d to %d\n", sig, (int)this->_guarded_child_pid); ::kill (this->_guarded_child_pid, sig); } @@ -437,7 +437,7 @@ void App::unsubscribe_from_all_signals_no_mutex() } } -int App::guardProcess (const qse_mchar_t* proc_name, /* TODO: get the list of signals to relay??? */) +int App::guardProcess (const qse_mchar_t* proc_name, const Sigset& signals) { while (1) { @@ -445,8 +445,8 @@ int App::guardProcess (const qse_mchar_t* proc_name, /* TODO: get the list of si if (pid == -1) return -1; if (pid == 0) break; // child -int _SigLink::State old_sig_states[QSE_NSIGS]; -this->subscribeToAllSignals(true); +//int _SigLink::State old_sig_states[QSE_NSIGS]; +//this->subscribeToAllSignals(true); this->_guarded_child_pid = pid; diff --git a/qse/samples/si/tcpsvr01.cpp b/qse/samples/si/tcpsvr01.cpp index 1802c2b3..beb34859 100644 --- a/qse/samples/si/tcpsvr01.cpp +++ b/qse/samples/si/tcpsvr01.cpp @@ -75,7 +75,13 @@ public: int run () { - if (this->guardProcess("myapp") > 0) + QSE::App::Sigset signals; + signals.set (SIGINT); + signals.set (SIGHUP); + signals.set (SIGTERM); + signals.set (SIGUSR1); + signals.set (SIGUSR2); + if (this->guardProcess("myapp", signals) > 0) { qse_printf (QSE_T("Stareting workd\n")); this->server.setThreadStackSize (256000);