| /*****************************************************************************\ |
| * polling.c - Definitions for polling handlers |
| ***************************************************************************** |
| * Copyright (C) SchedMD LLC. |
| * |
| * This file is part of Slurm, a resource management program. |
| * For details, see <https://slurm.schedmd.com/>. |
| * Please also read the included file: DISCLAIMER. |
| * |
| * Slurm is free software; you can redistribute it and/or modify it under |
| * the terms of the GNU General Public License as published by the Free |
| * Software Foundation; either version 2 of the License, or (at your option) |
| * any later version. |
| * |
| * In addition, as a special exception, the copyright holders give permission |
| * to link the code of portions of this program with the OpenSSL library under |
| * certain conditions as described in each individual source file, and |
| * distribute linked combinations including the two. You must obey the GNU |
| * General Public License in all respects for all of the code used other than |
| * OpenSSL. If you modify file(s) with this exception, you may extend this |
| * exception to your version of the file(s), but you are not obligated to do |
| * so. If you do not wish to do so, delete this exception statement from your |
| * version. If you delete this exception statement from all source files in |
| * the program, then also delete it here. |
| * |
| * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
| * details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with Slurm; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| \*****************************************************************************/ |
| |
| #include "src/common/log.h" |
| #include "src/common/read_config.h" |
| #include "src/common/macros.h" |
| #include "src/common/xassert.h" |
| |
| #include "src/conmgr/polling.h" |
| |
| #ifdef HAVE_EPOLL |
| #define DEFAULT_POLLING_MODE POLL_MODE_EPOLL |
| extern const poll_funcs_t epoll_funcs; |
| #else |
| #define DEFAULT_POLLING_MODE POLL_MODE_POLL |
| #endif /* HAVE_EPOLL */ |
| |
| #define T(mode) { mode, XSTRINGIFY(mode) } |
| static const struct { |
| poll_mode_t mode; |
| const char *string; |
| } modes[] = { |
| T(POLL_MODE_INVALID), |
| T(POLL_MODE_EPOLL), |
| T(POLL_MODE_POLL), |
| T(POLL_MODE_INVALID_MAX), |
| }; |
| |
| extern const poll_funcs_t poll_funcs; |
| |
| static poll_mode_t mode = POLL_MODE_INVALID; |
| static const poll_funcs_t *polling_funcs[] = { |
| #ifdef HAVE_EPOLL |
| &epoll_funcs, |
| #endif /* HAVE_EPOLL */ |
| &poll_funcs, |
| }; |
| |
| static const char *_mode_string(poll_mode_t find_mode) |
| { |
| for (int i = 0; i < ARRAY_SIZE(modes); i++) |
| if (modes[i].mode == find_mode) |
| return modes[i].string; |
| |
| fatal_abort("should never happen"); |
| } |
| |
| static const poll_funcs_t *_get_funcs(void) |
| { |
| for (int i = 0; i < ARRAY_SIZE(polling_funcs); i++) |
| if (polling_funcs[i]->mode == mode) |
| return polling_funcs[i]; |
| |
| fatal_abort("should never happen"); |
| } |
| |
| extern const char *pollctl_type_to_string(pollctl_fd_type_t type) |
| { |
| return _get_funcs()->type_to_string(type); |
| } |
| |
| extern void pollctl_init(const int max_connections) |
| { |
| if (mode == POLL_MODE_INVALID) |
| mode = DEFAULT_POLLING_MODE; |
| log_flag(CONMGR, "%s: [%s] Initializing with connection count %d", |
| __func__, _mode_string(mode), max_connections); |
| _get_funcs()->init(max_connections); |
| } |
| |
| extern void pollctl_set_mode(poll_mode_t new_mode) |
| { |
| /* This should only be called before polling has been initialized */ |
| xassert(mode == POLL_MODE_INVALID); |
| xassert(new_mode > POLL_MODE_INVALID); |
| xassert(new_mode < POLL_MODE_INVALID_MAX); |
| |
| mode = new_mode; |
| if (mode == DEFAULT_POLLING_MODE) |
| return; |
| |
| log_flag(CONMGR, "%s: Changing polling type: %s -> %s", |
| __func__, _mode_string(DEFAULT_POLLING_MODE), |
| _mode_string(mode)); |
| } |
| |
| extern void pollctl_fini(void) |
| { |
| log_flag(CONMGR, "%s: [%s] cleanup", __func__, _mode_string(mode)); |
| _get_funcs()->fini(); |
| } |
| |
| extern int pollctl_link_fd(int fd, pollctl_fd_type_t type, const char *con_name, |
| const char *caller) |
| { |
| return _get_funcs()->link_fd(fd, type, con_name, caller); |
| } |
| |
| extern int pollctl_relink_fd(int fd, pollctl_fd_type_t type, |
| const char *con_name, const char *caller) |
| { |
| return _get_funcs()->relink_fd(fd, type, con_name, caller); |
| } |
| |
| extern int pollctl_unlink_fd(int fd, const char *con_name, const char *caller) |
| { |
| return _get_funcs()->unlink_fd(fd, con_name, caller); |
| } |
| |
| extern int pollctl_poll(const char *caller) |
| { |
| return _get_funcs()->poll(caller); |
| } |
| |
| extern int pollctl_for_each_event(pollctl_event_func_t func, void *arg, |
| const char *func_name, const char *caller) |
| { |
| return _get_funcs()->for_each_event(func, arg, func_name, caller); |
| } |
| |
| extern void pollctl_interrupt(const char *caller) |
| { |
| _get_funcs()->interrupt(caller); |
| } |
| |
| extern bool pollctl_events_can_read(pollctl_events_t events) |
| { |
| return _get_funcs()->events_can_read(events); |
| } |
| |
| extern bool pollctl_events_can_write(pollctl_events_t events) |
| { |
| return _get_funcs()->events_can_write(events); |
| } |
| |
| extern bool pollctl_events_has_error(pollctl_events_t events) |
| { |
| return _get_funcs()->events_has_error(events); |
| } |
| |
| extern bool pollctl_events_has_hangup(pollctl_events_t events) |
| { |
| return _get_funcs()->events_has_hangup(events); |
| } |