#include #include // An object representing the arguments to an application singleton instance // invocation. This example just passes the raw contents of argv. class app_argsObj : virtual public x::obj { public: // They get stored in a vector proper. std::vector argv; app_argsObj() {} app_argsObj(int argc, char **argv_args) : argv(argv_args, argv_args+argc) { } ~app_argsObj() { } // ... and serialized template static void serialize(ptr_type ptr, iter_type &iter) { iter(ptr->argv); } void dump() const { const char *sep=""; for (auto &arg:argv) { std::cout << sep << arg; sep=" "; } std::cout << std::endl; } }; typedef x::ref app_args; typedef x::ptr app_argsptr; // A return value from the application singleton instance. This example // returns a std::string, a simple message. class ret_argsObj : virtual public x::obj { public: ret_argsObj() {} ~ret_argsObj() {} std::string message; ret_argsObj(const std::string &messageArg) : message(messageArg) {} template static void serialize(ptr_type ptr, iter_type &iter) { iter(ptr->message); } }; typedef x::ref ret_args; class appObj : virtual public x::obj { public: std::mutex mutex; std::condition_variable cond; bool quitflag; appObj() : quitflag(false) {} ~appObj() {} // The first singleton instance waits for another instance to be // called with a 'stop' argument. ret_args run(uid_t uid, const app_args &args) { std::cout << "Initial (uid " << uid << "): "; args->dump(); std::unique_lock lock(mutex); cond.wait(lock, [this] { return quitflag; }); return ret_args::create("Bye!"); } // Additional application singleton instance invocation. void instance(uid_t uid, const app_args &args, const ret_args &ret, const x::singletonapp::processed &flag, const x::ref &mcguffin) { flag->processed(); std::cout << "Additional (uid " << uid << "): "; args->dump(); ret->message="Processed"; if (args->argv.size() > 1 && args->argv[1] == "stop") stop(); } // Another way that the application singleton gets stopped. Typically // by a SIGINT or SIGHUP. void stop() { std::unique_lock lock(mutex); quitflag=true; cond.notify_all(); } }; typedef x::ref app; int main(int argc, char **argv) { const char *uid=getenv("SUID"); const char *same_env=getenv("SAME"); bool same=!same_env || atoi(same_env); auto ret=x::singletonapp::managed( // The application singleton factory [] { return app::create(); }, // Argument for this instance // invocation. app_args::create(argc, argv), (uid ? (uid_t)atoi(uid):getuid()), same ? 0700:0755, same); std::cout << "Result (uid " << ret.second << "): " << ret.first->message << std::endl; return 0; }