00001 // Internal version: Please do not publish! 00002 // (... until released under FreeBSD-like license *g*) 00003 // Code: Sebastian Mies <mies@tm.uka.de> 00004 00005 #include "asio_io_service.h" 00006 00007 #include <boost/asio.hpp> 00008 #include <boost/thread.hpp> 00009 00010 namespace ariba { 00011 namespace transport { 00012 namespace detail { 00013 00014 using namespace boost::asio; 00015 using namespace std; 00016 00017 asio_io_service* asio_io_service::singleton = NULL; 00018 00019 //#define DBG(x) cout << x << endl; 00020 #define DBG(x) 00021 00022 void asio_io_service::operator ()() { 00023 running = true; 00024 DBG("io_service started"); 00025 boost::asio::io_service::work work(*service); 00026 service->run(); 00027 DBG("io_service stopped"); 00028 if (destroy) { 00029 delete singleton; 00030 singleton = NULL; 00031 DBG(cout << "asio io_service singleton destroyed" << endl); 00032 } 00033 running = false; 00034 } 00035 00036 asio_io_service::asio_io_service() : 00037 references(1), running(false), destroy(false), thread(NULL), service(NULL) { 00038 service = new io_service(); 00039 } 00040 00041 asio_io_service::~asio_io_service() { 00042 if (running) { 00043 service->stop(); 00044 thread->join(); 00045 } 00046 if (thread != NULL) delete thread; 00047 if (service != NULL) delete service; 00048 thread = NULL; 00049 service = NULL; 00050 } 00051 00052 void asio_io_service::internal_start() { 00053 if (!running) { 00054 if (thread != NULL) delete thread; 00055 thread = new boost::thread(boost::ref(*this)); 00056 } 00057 } 00058 00059 void asio_io_service::internal_stop() { 00060 service->stop(); 00061 singleton->running = false; 00062 } 00063 00064 io_service& asio_io_service::alloc() { 00065 if (singleton != NULL) { 00066 DBG("new asio io_service reference"); 00067 singleton->references++; 00068 return *singleton->service; 00069 } else { 00070 DBG("creating new asio io_service singleton"); 00071 singleton = new asio_io_service(); 00072 return *singleton->service; 00073 } 00074 } 00075 00076 void asio_io_service::free() { 00077 if (singleton != NULL) { 00078 DBG("decreasing asio io_service reference"); 00079 singleton->references--; 00080 if (singleton->references == 0) { 00081 DBG("request asio io_service destruction"); 00082 if (singleton->running == false) { 00083 delete singleton; 00084 singleton = NULL; 00085 DBG("asio io_service singleton destroyed"); 00086 } else { 00087 singleton->destroy = true; 00088 singleton->service->stop(); 00089 } 00090 } 00091 } 00092 } 00093 00094 void asio_io_service::start() { 00095 singleton->internal_start(); 00096 } 00097 00098 void asio_io_service::stop() { 00099 singleton->internal_stop(); 00100 } 00101 00102 00103 }}} // namespace ariba::transport::detail