// ********************************************************************** // // Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #ifndef ICE_APPLICATION_H #define ICE_APPLICATION_H #include #include #include #include namespace Ice { using IceUtil::CtrlCHandler; using IceUtil::CtrlCHandlerCallback; #ifdef ICE_CPP11_MAPPING /** * Determines how the Application class handles signals. */ enum class SignalPolicy : unsigned char #else enum SignalPolicy #endif { /** Enables signal handling. */ HandleSignals, /** Disables signal handling, meaning signals retain their default behavior. */ NoSignalHandling }; /** * Singleton helper class that simplifies Ice initialization, finalization and signal handling. * An application uses this class by writing a subclass and implementing the run method. * \headerfile Ice/Ice.h */ class ICE_API Application { public: /** * The constructor configures the signal handling behavior. * @param policy Specifies whether to handle signals. If not specified, the default behavior * is to handle signals. */ Application(SignalPolicy policy = ICE_ENUM(SignalPolicy, HandleSignals)); #ifdef ICE_CPP11_MAPPING /// \cond IGNORE Application(const Application&) = delete; Application& operator=(const Application&) = delete; /// \endcond #endif virtual ~Application(); /** * Call this main() from the global main(). main() * initializes the Communicator, calls run() and destroys the * the Communicator upon return from run(). It handles all * exceptions properly, i.e., error message are printed if * exceptions propagate to main(), and the Communicator is always * destroyed, regardless of exceptions. * @param argc Specifies the number of arguments in argv. * @param argv The command-line arguments. * @param initData Configuration data for the new Communicator. * @param version Indicates the Ice version with which the application is compatible. If not * specified, the version of the Ice installation is used. * @return The application's exit status. */ int main(int argc, const char* const argv[], const InitializationData& initData = InitializationData(), int version = ICE_INT_VERSION); /** * Call this main() from the global main(). main() * initializes the Communicator, calls run() and destroys the * the Communicator upon return from run(). It handles all * exceptions properly, i.e., error message are printed if * exceptions propagate to main(), and the Communicator is always * destroyed, regardless of exceptions. * @param argc Specifies the number of arguments in argv. * @param argv The command-line arguments. * @param configFile The name of an Ice configuration file. * @param version Indicates the Ice version with which the application is compatible. If not * specified, the version of the Ice installation is used. * @return The application's exit status. */ int main(int argc, const char* const argv[], ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); #ifdef _WIN32 /** * Call this main() from the global main(). main() * initializes the Communicator, calls run() and destroys the * the Communicator upon return from run(). It handles all * exceptions properly, i.e., error message are printed if * exceptions propagate to main(), and the Communicator is always * destroyed, regardless of exceptions. * @param argc Specifies the number of arguments in argv. * @param argv The command-line arguments. * @param initData Configuration data for the new Communicator. * @param version Indicates the Ice version with which the application is compatible. If not * specified, the version of the Ice installation is used. * @return The application's exit status. */ int main(int argc, const wchar_t* const argv[], const InitializationData& initData = InitializationData(), int version = ICE_INT_VERSION); /** * Call this main() from the global main(). main() * initializes the Communicator, calls run() and destroys the * the Communicator upon return from run(). It handles all * exceptions properly, i.e., error message are printed if * exceptions propagate to main(), and the Communicator is always * destroyed, regardless of exceptions. * @param argc Specifies the number of arguments in argv. * @param argv The command-line arguments. * @param configFile The name of an Ice configuration file. * @param version Indicates the Ice version with which the application is compatible. If not * specified, the version of the Ice installation is used. * @return The application's exit status. */ int main(int argc, const wchar_t* const argv[], ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); #endif /** * Call this main() from the global main(). main() * initializes the Communicator, calls run() and destroys the * the Communicator upon return from run(). It handles all * exceptions properly, i.e., error message are printed if * exceptions propagate to main(), and the Communicator is always * destroyed, regardless of exceptions. * @param args The command-line arguments. * @param initData Configuration data for the new Communicator. * @param version Indicates the Ice version with which the application is compatible. If not * specified, the version of the Ice installation is used. * @return The application's exit status. */ int main(const StringSeq& args, const InitializationData& initData = InitializationData(), int version = ICE_INT_VERSION); /** * Call this main() from the global main(). main() * initializes the Communicator, calls run() and destroys the * the Communicator upon return from run(). It handles all * exceptions properly, i.e., error message are printed if * exceptions propagate to main(), and the Communicator is always * destroyed, regardless of exceptions. * @param args The command-line arguments. * @param configFile The name of an Ice configuration file. * @param version Indicates the Ice version with which the application is compatible. If not * specified, the version of the Ice installation is used. * @return The application's exit status. */ int main(const StringSeq& args, ICE_CONFIG_FILE_STRING configFile, int version = ICE_INT_VERSION); /** * run is given a copy of the remaining argc/argv arguments, * after the communicator initialization in the caller (main) * has removed all Ice-related arguments. * @param argc Specifies the number of arguments in argv. * @param argv The command-line arguments. * @return The application's exit status. */ virtual int run(int argc, char* argv[]) = 0; /** * Override this method to provide a custom application interrupt * hook. You must call callbackOnInterrupt for this method to * be called. Note that the interruptCallback can be called * concurrently with any other thread (including main) in your * application and thus must take appropriate concurrency * precautions. * @param signal The signal identifier. */ virtual void interruptCallback(int signal); /** * Obtains the application name, i.e., argv[0]. * @return The application's name. */ static const char* appName(); /** * Obtains the application's Communicator instance. * One limitation of this class is that there can only be one * Application instance, with one global Communicator, accessible * with this communicator() operation. This limitation is due to * how the signal handling functions below operate. If you require * multiple Communicators, then you cannot use this Application * framework class. * @return The application's communicator. */ static CommunicatorPtr communicator(); /** * Configures the application to destroy the communicator when one of the * monitored signals is raised. This is the default behavior. */ static void destroyOnInterrupt(); /** * Configures the application to shut down the communicator when one of the * monitored signals is raised. */ static void shutdownOnInterrupt(); /** * Configures the application to ignore signals. */ static void ignoreInterrupt(); /** * Configures the application to invoke interruptCallback when a signal occurs, * thereby giving the subclass responsibility for handling the signal. */ static void callbackOnInterrupt(); /** * Configures the application to ignore (but remember) a signal. * A stored signal (if any) can be handled later by calling releaseInterrupt. */ static void holdInterrupt(); /** * Processes a stored signal (if any) using the current signal handling configuration. */ static void releaseInterrupt(); /** * Indicates whether a signal handler was triggered. * This can be used once Communicator::waitForShutdown() returns to * test whether the shutdown was due to an interrupt (returns true) * or because Communicator::shutdown() was called (returns false). * @return True if a signal handler was triggered, false otherwise. */ static bool interrupted(); protected: /** * Helper function that implements the application logic. */ virtual int doMain(int, char*[], const InitializationData&, Int); /** * Used to synchronize the main thread and the CtrlCHandler thread. */ static IceUtil::Mutex _mutex; /** * Used to synchronize the main thread and the CtrlCHandler thread. */ static IceUtil::Cond _condVar; /** * True if a signal handling callback is currently executing. * Can change while run() and communicator->destroy() are running! */ static bool _callbackInProgress; /** * True if the communicator has been destroyed. * Can change while run() and communicator->destroy() are running! */ static bool _destroyed; /** * True if an interrupt signal was received. * Can change while run() and communicator->destroy() are running! */ static bool _interrupted; /** * The application's name. * Immutable during run() and until communicator->destroy() has returned. * Before and after run(), and once communicator->destroy() has returned, * we assume that only the main thread and CtrlCHandler threads are running. */ static std::string _appName; /** * The application's communicator. * Immutable during run() and until communicator->destroy() has returned. * Before and after run(), and once communicator->destroy() has returned, * we assume that only the main thread and CtrlCHandler threads are running. */ static CommunicatorPtr _communicator; /** * The signal-handling policy specified at construction. * Immutable during run() and until communicator->destroy() has returned. * Before and after run(), and once communicator->destroy() has returned, * we assume that only the main thread and CtrlCHandler threads are running. */ static SignalPolicy _signalPolicy; /** * The singleton instance. * Immutable during run() and until communicator->destroy() has returned. * Before and after run(), and once communicator->destroy() has returned, * we assume that only the main thread and CtrlCHandler threads are running. */ static Application* _application; private: static void holdInterruptCallback(int); static void destroyOnInterruptCallback(int); static void shutdownOnInterruptCallback(int); static void callbackOnInterruptCallback(int); #ifndef ICE_CPP11_MAPPING // // Not defined, make Application non-copyable // Application(const Application&); Application& operator=(const Application&); #endif }; } #endif