00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "config.h"
00025
00026 #include <algorithm>
00027 #include <cerrno>
00028 #include <cstring>
00029 #include <exception>
00030 #include <functional>
00031 #include <unistd.h>
00032
00033 #include <scalestack/event/handler.h>
00034 #include <scalestack/event/handler_service.h>
00035 #include <scalestack/kernel/core.h>
00036 #include <scalestack/kernel/module.h>
00037
00038 using namespace std;
00039
00040 namespace scalestack
00041 {
00042 namespace event
00043 {
00044
00045
00046
00047
00048
00049 handler_service::handler_service(kernel::module& module):
00050 kernel::service(module),
00051 _stop(false),
00052 _handler_count(),
00053 _service(static_cast<event::service&>(
00054 module.get_core().get_service("event"))),
00055 _pipe(),
00056 _handler_mutex(module),
00057 _handlers()
00058 {
00059 if (pipe(_pipe) == -1)
00060 _module.log_fatal(_("Failed pipe: %s:%d"), strerror(errno), errno);
00061 }
00062
00063 handler_service::~handler_service()
00064 {
00065 stop();
00066 close(_pipe[0]);
00067 close(_pipe[1]);
00068 }
00069
00070 void handler_service::stop(void)
00071 {
00072 _stop = true;
00073 _handler_mutex.lock();
00074 for_each(_handlers.begin(), _handlers.end(), mem_fun(&handler::shutdown));
00075
00076 char buffer[1024];
00077 while (_handler_count > 0)
00078 {
00079 _handler_mutex.unlock();
00080
00081 if (read(_pipe[0], buffer, sizeof(buffer)) == -1 && errno != EINTR)
00082 _module.log_fatal(_("Failed pipe read: %s:%d"), strerror(errno), errno);
00083
00084 _handler_mutex.lock();
00085 }
00086
00087 _handler_mutex.unlock();
00088 }
00089
00090
00091
00092
00093
00094 void handler_service::_start_handler(handler* handler)
00095 {
00096 _handler_mutex.lock();
00097 try
00098 {
00099 handler->_start();
00100 _handlers.insert(handler);
00101 ++_handler_count;
00102 if (_stop)
00103 handler->shutdown();
00104 }
00105 catch (exception&)
00106 {
00107 _handler_mutex.unlock();
00108 throw;
00109 }
00110 _handler_mutex.unlock();
00111 }
00112
00113 void handler_service::_stop_handler(handler* handler)
00114 {
00115 _handler_mutex.lock();
00116 _handlers.erase(handler);
00117 _handler_mutex.unlock();
00118
00119 delete handler;
00120 _handler_mutex.lock();
00121 --_handler_count;
00122
00123 if (_stop)
00124 {
00125 if (write(_pipe[1], "\0", 1) == -1 && errno != EINTR)
00126 {
00127 _handler_mutex.unlock();
00128 _module.log_fatal(_("Failed pipe write: %s:%d"), strerror(errno), errno);
00129 }
00130 }
00131 _handler_mutex.unlock();
00132 }
00133
00134 }
00135 }