Thread: [Cppcms-users] Mounting asynchronous applications
Brought to you by:
artyom-beilis
From: Julian P. <ju...@wh...> - 2010-10-11 00:43:39
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hallo, I currently experience a problem when mounting an asynchronous cppcms::application I wrote. I use the following code to mount the application: booster::intrusive_ptr<cppcms::application> app = factory.getApplication(srv); srv.applications_pool().mount(app,mp); Where - - factory.getApplication() would return a (raw) pointer to an instance of my application - - srv is, as you can guess, a cppcms::service instance - - mp means an instance of cppcms::mount_point indicating the mount point under which my application should be accessible The problem I encounter is, that apparently my application is just destroyed after having been constructed by the call to factory.getApplication(), so there seems to be a problem with the reference count of the intrusive pointer. For writing the application I roughly followed the chat example, which means I did add no methods or likewise for the intrusive ptr implementation but only derived cppcms::application and wrote some client handling methods. I also tried returning an intrusive ptr instead of the raw pointer in factory.getApplication(), but this did not change the behaviour. I tried to pass the raw pointer to the mount method without wrapping it in an intrusive pointer beforehand, but encountered same results as before: application is immediately destroyed after having been constructed, while the cppcms::service keeps running, including some synchronously mounted applications(factories). I hope you can help me with fixing my problem, Julian -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQIcBAEBAgAGBQJMsl3nAAoJENidYKvYQHlQaO0P/3aa4IzWDAYgRXEkHoaNI1nk t2VPG4/yA0Gxzvfoj9Pzz7oGBD80vs1VFMUSfEu6AvD9slaZe2eBunV1PhvNLoeH aOpSqfVJUSOXzvrtNT+8OgsNQE4afS7Uzb5Ah4GxPckGvUgpkVdLYEZT7zp7hR77 Yi/ylp0+/zUtKkEVpUjFEbcHg8LXS1JggdTV3krfZGZasI0uBR3PqWEp09FBAb3y x3pm48hszobB9aMntwYqO8TyIsfd5x1tf+VOS4IavKhEWYw1fYhfc5AV8ZdSCrsn abM2YkkgiLHL1iy2V6Y1S45F1HWNdWdOuwGXp7jLVjBYl9K2H+Kk/r7v3FTnL6l1 1dEfSlVxRpzaK6fItT7upFuYpTf/JPoMc0AQksA4cFRd4NsJHbd7LlTxCs7WKzAg VzJCu+yIjDfC+Ct5EIKhxW+2w0Fo3grDGLLxGIF++3976hFweqHpVuoRQPsp9agu VPJps0+aDVOqjg/UdU6uL7Icftqm8Dn+LihZebBF25cErOOmbiwCA1orVhZ81Dlo f9RNCOsI0o4pMQjSUkr/7clq9RoHDOkZOH2njw1z/aVKjWh/41B1lvqORm/2k9g3 wk5CUdaZk8WtawM1WkG6EwMa0jEjUuY8uytPzFKATbHhcnUBuATNO2Evr9Vp25Jx Q3l28zh6akoeV5QlfpGv =888E -----END PGP SIGNATURE----- |
From: Artyom <art...@ya...> - 2010-10-11 07:48:40
|
> > The problem I encounter is, that apparently my application is just > destroyed after having been constructed by the call to > factory.getApplication(), so there seems to be a problem with the > reference count of the intrusive pointer. > For writing the application I > roughly followed the chat example, which means I did add no methods or > likewise for the intrusive ptr implementation but only derived > cppcms::application and wrote some client handling methods. > I also tried returning an intrusive ptr instead of the raw pointer in > factory.getApplication(), but this did not change the behaviour. > I tried to pass the raw pointer to the mount method without wrapping it > in an intrusive pointer beforehand, but encountered same results as > before: application is immediately destroyed after having been > constructed, while the cppcms::service keeps running, including some > synchronously mounted applications(factories). > > I hope you can help me with fixing my problem, This is done by design. The applications pool **does not own** your asynchronous application, it only keeps a reference on it and when such application destroyed it is automatically unregistered in applications pool. You have two ways to keep it alive: ------------------------------------------------------------ Keep a pointer (intrusive_ptr) on it in some place you know ------------------------------------------------------------ Just create a place where you can store intrusive_ptr on your application and keep it alive, like in chat example, it was kept on stack. ------------------------------------------------------------ Make event loop to own the application by giving it some outstanding jobs, for example some timeout. ------------------------------------------------------------ By this design when the asynchronous application is not in use any more, it is automatically destroyed and unregistered. Generally if you have such asynchronous application created dynamically, they probably have some life time so they destroyed at some point, the basic case would be timeout. So just add a booster::aio::deadline_time to it and start asynchronous wait on this timer like this: class my_app: public cppcms::application { public: my_app(cppcms::service &s) : cppcms::application(s), timer_(s.get_io_service()) { } void async_start() { timer_.expires_from_now(10); // seconds booster::intrusive_ptr<my_app> self(this); timer_.async_wait(boost::bind(&my_app::on_timeout,self)); } void on_timeout() { /// done or restart by calling async_start } }; Now before you mount your application just call async_start, then the timer would pass the handler that owns the application (the self pointer we created) to the event loop and it owns the application, once all outstanding jobs are completed, it would be destroyed, it may be a timeout or may be some other source. For example in same way you may create an application that listens to plain TCP socket and HTTP requests. I may suggest to take a look on Boost.Asio and way it works, because CppCMS's and Booster's event loop is based on its ideas (actually before Booster was created CppCMS used Boost.Asio inside) Regards, Artyom P.S.: The code sample is not tested |