
Worker is now the base class of all workers. It has a message queue and can be run in a thread of its own, or in the calling thread. Worker can not be used as such, but a concrete worker class must be derived from it. Currently there is only one concrete class RoutingWorker. There is some overlapping in functionality between Worker and RoutingWorker, as there is e.g. a need for broadcasting a message to all routing workers, but not to other workers. Currently other workers can not be created as the array for holding the pointers to the workers is exactly as large as there will be RoutingWorkers. That will be changed so that the maximum number of threads is hardwired to some ridiculous value such as 128. That's the first step in the path towards a situation where the number of worker threads can be changed at runtime.
174 lines
5.1 KiB
C++
174 lines
5.1 KiB
C++
#pragma once
|
|
/*
|
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
|
*
|
|
* Change Date: 2020-01-01
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
#include <maxscale/cppdefs.hh>
|
|
#include <maxscale/routingworker.h>
|
|
#include "worker.hh"
|
|
#include "session.hh"
|
|
|
|
namespace maxscale
|
|
{
|
|
|
|
class RoutingWorker : public Worker
|
|
, private MXS_POLL_DATA
|
|
{
|
|
RoutingWorker(const RoutingWorker&) = delete;
|
|
RoutingWorker& operator = (const RoutingWorker&) = delete;
|
|
|
|
public:
|
|
enum
|
|
{
|
|
MAIN = -1
|
|
};
|
|
|
|
typedef Registry<MXS_SESSION> SessionsById;
|
|
typedef std::vector<DCB*> Zombies;
|
|
|
|
/**
|
|
* Initialize the routing worker mechanism.
|
|
*
|
|
* To be called once at process startup. This will cause as many workers
|
|
* to be created as the number of threads defined.
|
|
*
|
|
* @return True if the initialization succeeded, false otherwise.
|
|
*/
|
|
static bool init();
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
static void finish();
|
|
|
|
/**
|
|
* Add a file descriptor to the epoll instance shared between all workers.
|
|
* Events occuring on the provided file descriptor will be handled by all
|
|
* workers. This is primarily intended for listening sockets where the
|
|
* only event is EPOLLIN, signaling that accept() can be used on the listening
|
|
* socket for creating a connected socket to a client.
|
|
*
|
|
* @param fd The file descriptor to be added.
|
|
* @param events Mask of epoll event types.
|
|
* @param pData The poll data associated with the descriptor:
|
|
*
|
|
* data->handler : Handler that knows how to deal with events
|
|
* for this particular type of 'struct mxs_poll_data'.
|
|
* data->thread.id: 0
|
|
*
|
|
* @return True, if the descriptor could be added, false otherwise.
|
|
*/
|
|
static bool add_shared_fd(int fd, uint32_t events, MXS_POLL_DATA* pData);
|
|
|
|
/**
|
|
* Remove a file descriptor from the epoll instance shared between all workers.
|
|
*
|
|
* @param fd The file descriptor to be removed.
|
|
*
|
|
* @return True on success, false on failure.
|
|
*/
|
|
static bool remove_shared_fd(int fd);
|
|
|
|
/**
|
|
* Register zombie for later deletion.
|
|
*
|
|
* @param pZombie DCB that will be deleted at end of event loop.
|
|
*
|
|
* @note The DCB must be owned by this worker.
|
|
*/
|
|
void register_zombie(DCB* pZombie);
|
|
|
|
/**
|
|
* Return a reference to the session registry of this worker.
|
|
*
|
|
* @return Session registry.
|
|
*/
|
|
SessionsById& session_registry();
|
|
|
|
/**
|
|
* Return the worker associated with the provided worker id.
|
|
*
|
|
* @param worker_id A worker id. By specifying MAIN, the routing worker
|
|
* running in the main thread will be returned.
|
|
*
|
|
* @return The corresponding worker instance, or NULL if the id does
|
|
* not correspond to a worker.
|
|
*/
|
|
static RoutingWorker* get(int worker_id);
|
|
|
|
/**
|
|
* Return the worker associated with the current thread.
|
|
*
|
|
* @return The worker instance, or NULL if the current thread does not have a worker.
|
|
*/
|
|
static RoutingWorker* get_current();
|
|
|
|
/**
|
|
* Return the worker id associated with the current thread.
|
|
*
|
|
* @return A worker instance, or -1 if the current thread does not have a worker.
|
|
*/
|
|
static int get_current_id();
|
|
|
|
/**
|
|
* Starts all routing workers but the main worker (the one running in
|
|
* the main thread).
|
|
*
|
|
* @return True, if all secondary workers could be started.
|
|
*/
|
|
static bool start_threaded_workers();
|
|
|
|
/**
|
|
* Waits for all threaded workers.
|
|
*/
|
|
static void join_threaded_workers();
|
|
|
|
/**
|
|
* Deprecated
|
|
*/
|
|
static void set_nonblocking_polls(unsigned int nbpolls);
|
|
|
|
/**
|
|
* Deprecated
|
|
*/
|
|
static void set_maxwait(unsigned int maxwait);
|
|
|
|
private:
|
|
RoutingWorker();
|
|
virtual ~RoutingWorker();
|
|
|
|
static RoutingWorker* create(int epoll_listener_fd);
|
|
|
|
bool pre_run(); // override
|
|
void post_run(); // override
|
|
void epoll_tick(); // override
|
|
|
|
void delete_zombies();
|
|
|
|
static uint32_t epoll_instance_handler(struct mxs_poll_data* data, int wid, uint32_t events);
|
|
uint32_t handle_epoll_events(uint32_t events);
|
|
|
|
private:
|
|
SessionsById m_sessions; /*< A mapping of session_id->MXS_SESSION. The map
|
|
* should contain sessions exclusive to this
|
|
* worker and not e.g. listener sessions. For now,
|
|
* it's up to the protocol to decide whether a new
|
|
* session is added to the map. */
|
|
Zombies m_zombies; /*< DCBs to be deleted. */
|
|
};
|
|
|
|
}
|