diff --git a/include/maxscale/worker.hh b/include/maxscale/worker.hh index 8e82efdfb..a3e76bb58 100644 --- a/include/maxscale/worker.hh +++ b/include/maxscale/worker.hh @@ -564,8 +564,7 @@ public: /** * Initialize the worker mechanism. * - * To be called once at process startup. This will cause as many workers - * to be created as the number of threads defined. + * To be called once at process startup. * * @return True if the initialization succeeded, false otherwise. */ @@ -574,13 +573,23 @@ public: /** * Finalize the worker mechanism. * - * To be called once at process shutdown. This will cause all workers - * to be destroyed. When the function is called, no worker should be - * running anymore. + * To be called once at process shutdown. */ static void finish(); - Worker(); + enum + { + MAX_EVENTS = 1000 + }; + + /** + * Constructs a worker. + * + * @param max_events The maximum number of events that can be returned by + * one call to epoll_wait. + */ + Worker(int max_events = MAX_EVENTS); + virtual ~Worker(); int load(Load::counter_t counter) @@ -1189,6 +1198,7 @@ private: typedef std::multimap DelayedCallsByTime; typedef std::unordered_map DelayedCallsById; + uint32_t m_max_events; /*< Maximum numer of events in each epoll_wait call. */ STATISTICS m_statistics; /*< Worker statistics. */ MessageQueue* m_pQueue; /*< The message queue of the worker. */ std::thread m_thread; /*< The thread object of the worker. */ diff --git a/server/core/internal/poll.hh b/server/core/internal/poll.hh index b2ef7f5c2..f877226ce 100644 --- a/server/core/internal/poll.hh +++ b/server/core/internal/poll.hh @@ -22,8 +22,6 @@ struct mxs_worker; -#define MAX_EVENTS 1000 - enum poll_message { POLL_MSG_CLEAN_PERSISTENT = 0x01 diff --git a/server/core/worker.cc b/server/core/worker.cc index a4542e526..411e5bc5f 100644 --- a/server/core/worker.cc +++ b/server/core/worker.cc @@ -35,7 +35,6 @@ #include "internal/dcb.h" #include "internal/modules.h" -#include "internal/poll.hh" #include "internal/service.hh" #include "internal/statistics.h" @@ -280,7 +279,9 @@ namespace int create_epoll_instance() { - int fd = ::epoll_create(MAX_EVENTS); + // Since Linux kernel 2.6.8, the size argument is ignored, but must be positive. + + int fd = ::epoll_create(1); if (fd == -1) { @@ -297,9 +298,10 @@ int create_epoll_instance() //static uint32_t Worker::s_next_delayed_call_id = 1; -Worker::Worker() +Worker::Worker(int max_events) : m_epoll_fd(create_epoll_instance()) , m_state(STOPPED) + , m_max_events(max_events) , m_pQueue(NULL) , m_started(false) , m_should_shutdown(false) @@ -308,6 +310,8 @@ Worker::Worker() , m_nTotal_descriptors(0) , m_pTimer(new PrivateTimer(this, this, &Worker::tick)) { + ss_dassert(max_events > 0); + if (m_epoll_fd != -1) { m_pQueue = MessageQueue::create(this); @@ -733,7 +737,7 @@ void Worker::resolve_poll_error(int fd, int errornum, int op) */ void Worker::poll_waitevents() { - struct epoll_event events[MAX_EVENTS]; + struct epoll_event events[m_max_events]; m_state = IDLE; @@ -761,7 +765,7 @@ void Worker::poll_waitevents() } m_load.about_to_wait(now); - nfds = epoll_wait(m_epoll_fd, events, MAX_EVENTS, timeout); + nfds = epoll_wait(m_epoll_fd, events, m_max_events, timeout); m_load.about_to_work(); if (nfds == -1 && errno != EINTR)