MXS-1915 Remove id from mxs::Worker
The id has now been moved from mxs::Worker to mxs::RoutingWorker and the implications are felt in many places. The primary need for the id was to be able to access worker specfic data, maintained outside of a routing worker, when given a worker (the id is used to index into an array). Slightly related to that was the need to be able to iterate over all workers. That obviously implies some kind of collection. That causes all sorts of issues if there is a need for being able to create and destroy a worker at runtime. With the id removed from mxs::Worker all those issues are gone, and its perfectly ok to create and destory mxs::Workers as needed. Further, while there is a need to broadcast a particular message to all _routing_ workers, it hardly makes sense to broadcast a particular message too _all_ workers. Consequently, only routing workers are kept in a collection and all static member functions dealing with all workers (e.g. broadcast) have now been moved to mxs::RoutingWorker. Now, instead of passing the id around we instead deal directly with the worker pointer. Later the data in all those external arrays will be moved into mxs::[Worker|RoutingWorker] so that worker related data is maintained in exactly one place.
This commit is contained in:
@ -193,9 +193,9 @@ public:
|
||||
private:
|
||||
MessageQueue(Handler* pHandler, int read_fd, int write_fd);
|
||||
|
||||
uint32_t handle_poll_events(int thread_id, uint32_t events);
|
||||
uint32_t handle_poll_events(Worker* pWorker, uint32_t events);
|
||||
|
||||
static uint32_t poll_handler(MXS_POLL_DATA* pData, int thread_id, uint32_t events);
|
||||
static uint32_t poll_handler(MXS_POLL_DATA* pData, void* worker, uint32_t events);
|
||||
|
||||
private:
|
||||
Handler& m_handler;
|
||||
|
||||
@ -39,12 +39,13 @@ struct mxs_poll_data;
|
||||
* 'struct mxs_poll_data' structure.
|
||||
*
|
||||
* @param data The `mxs_poll_data` instance that contained this function pointer.
|
||||
* @param wid The worker thread id.
|
||||
* @param worker The worker.
|
||||
* @param events The epoll events.
|
||||
*
|
||||
* @return A combination of mxs_poll_action_t enumeration values.
|
||||
*/
|
||||
typedef uint32_t (*mxs_poll_handler_t)(struct mxs_poll_data* data, int wid, uint32_t events);
|
||||
// TODO: Change worker to mxs::Worker once this is C++-ified.
|
||||
typedef uint32_t (*mxs_poll_handler_t)(struct mxs_poll_data* data, void* worker, uint32_t events);
|
||||
|
||||
typedef struct mxs_poll_data
|
||||
{
|
||||
@ -52,45 +53,4 @@ typedef struct mxs_poll_data
|
||||
void* owner; /*< Owning worker. */
|
||||
} MXS_POLL_DATA;
|
||||
|
||||
/**
|
||||
* A file descriptor should be added to the poll set of all workers.
|
||||
*/
|
||||
#define MXS_WORKER_ALL -1
|
||||
|
||||
/**
|
||||
* Add a file descriptor with associated data to the poll set.
|
||||
*
|
||||
* @param wid `MXS_WORKER_ALL` if the file descriptor should be added to the
|
||||
* poll set of all workers, `MXS_WORKER_ANY` if the file descriptor
|
||||
* should be added to some worker, otherwise the id of a worker.
|
||||
* @param fd The file descriptor to be added.
|
||||
* @param events Mask of epoll event types.
|
||||
* @param data The structure containing the file descriptor to be
|
||||
* added.
|
||||
*
|
||||
* data->handler : Handler that knows how to deal with events
|
||||
* for this particular type of 'struct mxs_poll_data'.
|
||||
* data->thread.id: Will be updated by `poll_add_fd_to_worker`.
|
||||
*
|
||||
* @attention If the descriptor should be added to all workers, then the worker
|
||||
* thread id will be 0.
|
||||
*
|
||||
* @attention The provided file descriptor *must* be non-blocking.
|
||||
*
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
bool poll_add_fd_to_worker(int wid, int fd, uint32_t events, MXS_POLL_DATA* data);
|
||||
|
||||
|
||||
/**
|
||||
* Remove a file descriptor from a poll set.
|
||||
*
|
||||
* @param wid `MXS_WORKER_ALL` if the file descriptor should be removed from
|
||||
* the poll set of all workers; otherwise the id of a worker.
|
||||
* @param fd The file descriptor to be removed.
|
||||
*
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
bool poll_remove_fd_from_worker(int wid, int fd);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
||||
@ -59,7 +59,7 @@ public:
|
||||
private:
|
||||
static LocalClient* create(MXS_SESSION* session, const char* ip, uint64_t port);
|
||||
LocalClient(MXS_SESSION* session, int fd);
|
||||
static uint32_t poll_handler(struct mxs_poll_data* data, int wid, uint32_t events);
|
||||
static uint32_t poll_handler(struct mxs_poll_data* data, void* worker, uint32_t events);
|
||||
void process(uint32_t events);
|
||||
GWBUF* read_complete_packet();
|
||||
void drain_queue();
|
||||
|
||||
@ -45,7 +45,7 @@ enum mxs_worker_msg_id
|
||||
/**
|
||||
* Function call message.
|
||||
*
|
||||
* arg1: Pointer to function with the prototype: void (*)(int thread_id, void* arg2);
|
||||
* arg1: Pointer to function with the prototype: void (*)(MXS_WORKER*, void* arg2);
|
||||
* arg2: Second argument for the function passed in arg1.
|
||||
*/
|
||||
MXS_WORKER_MSG_CALL
|
||||
@ -76,25 +76,4 @@ MXS_WORKER* mxs_worker_get_current();
|
||||
*/
|
||||
bool mxs_worker_post_message(MXS_WORKER* worker, uint32_t msg_id, intptr_t arg1, intptr_t arg2);
|
||||
|
||||
/**
|
||||
* @brief Convert a worker to JSON format
|
||||
*
|
||||
* @param host Hostname of this server
|
||||
* @param id ID of the worker
|
||||
*
|
||||
* @return JSON resource representing the worker
|
||||
*/
|
||||
json_t* mxs_worker_to_json(const char* host, int id);
|
||||
|
||||
/**
|
||||
* Convert workers into JSON format
|
||||
*
|
||||
* @param host Hostname of this server
|
||||
*
|
||||
* @return A JSON resource collection of workers
|
||||
*
|
||||
* @see mxs_json_resource()
|
||||
*/
|
||||
json_t* mxs_worker_list_to_json(const char* host);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
||||
@ -466,9 +466,9 @@ protected:
|
||||
virtual void tick() = 0;
|
||||
|
||||
private:
|
||||
uint32_t handle(int wid, uint32_t events);
|
||||
uint32_t handle(Worker* pWorker, uint32_t events);
|
||||
|
||||
static uint32_t handler(MXS_POLL_DATA* pThis, int wid, uint32_t events);
|
||||
static uint32_t handler(MXS_POLL_DATA* pThis, void* pWorker, uint32_t events);
|
||||
|
||||
private:
|
||||
int m_fd; /**< The timerfd descriptor. */
|
||||
@ -578,16 +578,6 @@ public:
|
||||
Worker();
|
||||
virtual ~Worker();
|
||||
|
||||
/**
|
||||
* Returns the id of the worker
|
||||
*
|
||||
* @return The id of the worker.
|
||||
*/
|
||||
int id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
int load(Load::counter_t counter)
|
||||
{
|
||||
return m_load.percentage(counter);
|
||||
@ -617,26 +607,6 @@ public:
|
||||
return m_statistics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns statistics for all workers.
|
||||
*
|
||||
* @return Combined statistics.
|
||||
*
|
||||
* @attentions The statistics may no longer be accurate by the time it has
|
||||
* been returned. The returned values may also not represent a
|
||||
* 100% consistent set.
|
||||
*/
|
||||
static STATISTICS get_statistics();
|
||||
|
||||
/**
|
||||
* Return a specific combined statistic value.
|
||||
*
|
||||
* @param what What to return.
|
||||
*
|
||||
* @return The corresponding value.
|
||||
*/
|
||||
static int64_t get_one_statistic(POLL_STAT what);
|
||||
|
||||
/**
|
||||
* Return this worker's statistics.
|
||||
*
|
||||
@ -775,71 +745,6 @@ public:
|
||||
return post(std::auto_ptr<DisposableTask>(sTask.release()), mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts a task to all workers for execution.
|
||||
*
|
||||
* @param pTask The task to be executed.
|
||||
* @param pSem If non-NULL, will be posted once per worker when the task's
|
||||
* `execute` return.
|
||||
*
|
||||
* @return How many workers the task was posted to.
|
||||
*
|
||||
* @attention The very same task will be posted to all workers. The task
|
||||
* should either not have any sharable data or then it should
|
||||
* have data specific to each worker that can be accessed
|
||||
* without locks.
|
||||
*/
|
||||
static size_t broadcast(Task* pTask, Semaphore* pSem = NULL);
|
||||
|
||||
/**
|
||||
* Posts a task to all workers for execution.
|
||||
*
|
||||
* @param pTask The task to be executed.
|
||||
*
|
||||
* @return How many workers the task was posted to.
|
||||
*
|
||||
* @attention The very same task will be posted to all workers. The task
|
||||
* should either not have any sharable data or then it should
|
||||
* have data specific to each worker that can be accessed
|
||||
* without locks.
|
||||
*
|
||||
* @attention Once the task has been executed by all workers, it will
|
||||
* be deleted.
|
||||
*/
|
||||
static size_t broadcast(std::auto_ptr<DisposableTask> sTask);
|
||||
|
||||
template<class T>
|
||||
static size_t broadcast(std::auto_ptr<T> sTask)
|
||||
{
|
||||
return broadcast(std::auto_ptr<DisposableTask>(sTask.release()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a task on all workers in serial mode (the task is executed
|
||||
* on at most one worker thread at a time). When the function returns
|
||||
* the task has been executed on all workers.
|
||||
*
|
||||
* @param task The task to be executed.
|
||||
*
|
||||
* @return How many workers the task was posted to.
|
||||
*
|
||||
* @warning This function is extremely inefficient and will be slow compared
|
||||
* to the other functions. Only use this function when printing thread-specific
|
||||
* data to stdout.
|
||||
*/
|
||||
static size_t execute_serially(Task& task);
|
||||
|
||||
/**
|
||||
* Executes a task on all workers concurrently and waits until all workers
|
||||
* are done. That is, when the function returns the task has been executed
|
||||
* by all workers.
|
||||
*
|
||||
* @param task The task to be executed.
|
||||
*
|
||||
* @return How many workers the task was posted to.
|
||||
*/
|
||||
static size_t execute_concurrently(Task& task);
|
||||
|
||||
/**
|
||||
* Post a message to a worker.
|
||||
*
|
||||
@ -857,46 +762,6 @@ public:
|
||||
*/
|
||||
bool post_message(uint32_t msg_id, intptr_t arg1, intptr_t arg2);
|
||||
|
||||
/**
|
||||
* Broadcast a message to all worker.
|
||||
*
|
||||
* @param msg_id The message id.
|
||||
* @param arg1 Message specific first argument.
|
||||
* @param arg2 Message specific second argument.
|
||||
*
|
||||
* @return The number of messages posted; if less that ne number of workers
|
||||
* then some postings failed.
|
||||
*
|
||||
* @attention The return value tells *only* whether message could be posted,
|
||||
* *not* that it has reached the worker.
|
||||
*
|
||||
* @attentsion Exactly the same arguments are passed to all workers. Take that
|
||||
* into account if the passed data must be freed.
|
||||
*
|
||||
* @attention This function is signal safe.
|
||||
*/
|
||||
static size_t broadcast_message(uint32_t msg_id, intptr_t arg1, intptr_t arg2);
|
||||
|
||||
/**
|
||||
* Initate shutdown of all workers.
|
||||
*
|
||||
* @attention A call to this function will only initiate the shutdowm,
|
||||
* the workers will not have shut down when the function returns.
|
||||
*
|
||||
* @attention This function is signal safe.
|
||||
*/
|
||||
static void shutdown_all();
|
||||
|
||||
/**
|
||||
* Return the worker associated with the provided worker id.
|
||||
*
|
||||
* @param worker_id A worker id.
|
||||
*
|
||||
* @return The corresponding worker instance, or NULL if the id does
|
||||
* not correspond to a worker.
|
||||
*/
|
||||
static Worker* get(int worker_id);
|
||||
|
||||
/**
|
||||
* Return the worker associated with the current thread.
|
||||
*
|
||||
@ -904,13 +769,6 @@ public:
|
||||
*/
|
||||
static Worker* 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();
|
||||
|
||||
/**
|
||||
* Push a function for delayed execution.
|
||||
*
|
||||
@ -1034,6 +892,21 @@ public:
|
||||
bool cancel_delayed_call(uint32_t id);
|
||||
|
||||
protected:
|
||||
const int m_epoll_fd; /*< The epoll file descriptor. */
|
||||
state_t m_state; /*< The state of the worker */
|
||||
|
||||
static void inc_ref(WorkerDisposableTask* pTask)
|
||||
{
|
||||
pTask->inc_ref();
|
||||
}
|
||||
|
||||
static void dec_ref(WorkerDisposableTask* pTask)
|
||||
{
|
||||
pTask->dec_ref();
|
||||
}
|
||||
|
||||
bool post_disposable(DisposableTask* pTask, enum execute_mode_t mode = EXECUTE_AUTO);
|
||||
|
||||
/**
|
||||
* Called by Worker::run() before starting the epoll loop.
|
||||
*
|
||||
@ -1067,11 +940,6 @@ protected:
|
||||
*/
|
||||
static void resolve_poll_error(int fd, int err, int op);
|
||||
|
||||
protected:
|
||||
const int m_id; /*< The id of the worker. */
|
||||
const int m_epoll_fd; /*< The epoll file descriptor. */
|
||||
state_t m_state; /*< The state of the worker */
|
||||
|
||||
private:
|
||||
class DelayedCall;
|
||||
friend class DelayedCall;
|
||||
@ -1259,8 +1127,6 @@ private:
|
||||
uint32_t add_delayed_call(DelayedCall* pDelayed_call);
|
||||
void adjust_timer();
|
||||
|
||||
bool post_disposable(DisposableTask* pTask, enum execute_mode_t mode = EXECUTE_AUTO);
|
||||
|
||||
void handle_message(MessageQueue& queue, const MessageQueue::Message& msg); // override
|
||||
|
||||
static void thread_main(void* arg);
|
||||
|
||||
Reference in New Issue
Block a user