|
| 1 | +/* |
| 2 | + +----------------------------------------------------------------------+ |
| 3 | + | Copyright © The PHP Group and Contributors. | |
| 4 | + +----------------------------------------------------------------------+ |
| 5 | + | This source file is subject to the Modified BSD License that is | |
| 6 | + | bundled with this package in the file LICENSE, and is available | |
| 7 | + | through the World Wide Web at <https://www.php.net/license/>. | |
| 8 | + | | |
| 9 | + | SPDX-License-Identifier: BSD-3-Clause | |
| 10 | + +----------------------------------------------------------------------+ |
| 11 | + | Authors: Jakub Zelenka <bukka@php.net> | |
| 12 | + +----------------------------------------------------------------------+ |
| 13 | +*/ |
| 14 | + |
| 15 | +#ifndef PHP_POLL_H |
| 16 | +#define PHP_POLL_H |
| 17 | + |
| 18 | +#include "php.h" |
| 19 | +#include "php_network.h" |
| 20 | + |
| 21 | +#include <time.h> |
| 22 | + |
| 23 | +/* ----- Public generic API ----- */ |
| 24 | + |
| 25 | +/* clang-format off */ |
| 26 | + |
| 27 | +/* Event types */ |
| 28 | +#define PHP_POLL_READ 0x01 |
| 29 | +#define PHP_POLL_WRITE 0x02 |
| 30 | +#define PHP_POLL_ERROR 0x04 |
| 31 | +#define PHP_POLL_HUP 0x08 |
| 32 | +#define PHP_POLL_RDHUP 0x10 |
| 33 | +#define PHP_POLL_ONESHOT 0x20 |
| 34 | +#define PHP_POLL_ET 0x40 /* Edge-triggered */ |
| 35 | + |
| 36 | +/* Poll flags */ |
| 37 | +#define PHP_POLL_FLAG_PERSISTENT 0x01 |
| 38 | +#define PHP_POLL_FLAG_RAW_EVENTS 0x02 |
| 39 | + |
| 40 | +/* Poll backend types */ |
| 41 | +typedef enum { |
| 42 | + PHP_POLL_BACKEND_AUTO = -1, |
| 43 | + PHP_POLL_BACKEND_POLL = 0, |
| 44 | + PHP_POLL_BACKEND_EPOLL, |
| 45 | + PHP_POLL_BACKEND_KQUEUE, |
| 46 | + PHP_POLL_BACKEND_EVENTPORT, |
| 47 | + PHP_POLL_BACKEND_WSAPOLL |
| 48 | +} php_poll_backend_type; |
| 49 | + |
| 50 | +/* Error code constants for exception codes */ |
| 51 | +#define PHP_POLL_ERROR_CODE_NONE 0 |
| 52 | +#define PHP_POLL_ERROR_CODE_SYSTEM 1 |
| 53 | +#define PHP_POLL_ERROR_CODE_NOMEM 2 |
| 54 | +#define PHP_POLL_ERROR_CODE_INVALID 3 |
| 55 | +#define PHP_POLL_ERROR_CODE_EXISTS 4 |
| 56 | +#define PHP_POLL_ERROR_CODE_NOTFOUND 5 |
| 57 | +#define PHP_POLL_ERROR_CODE_TIMEOUT 6 |
| 58 | +#define PHP_POLL_ERROR_CODE_INTERRUPTED 7 |
| 59 | +#define PHP_POLL_ERROR_CODE_PERMISSION 8 |
| 60 | +#define PHP_POLL_ERROR_CODE_TOOBIG 9 |
| 61 | +#define PHP_POLL_ERROR_CODE_AGAIN 10 |
| 62 | +#define PHP_POLL_ERROR_CODE_NOSUPPORT 11 |
| 63 | + |
| 64 | +/* Error codes */ |
| 65 | +typedef enum { |
| 66 | + PHP_POLL_ERR_NONE = PHP_POLL_ERROR_CODE_NONE, /* No error */ |
| 67 | + PHP_POLL_ERR_SYSTEM = PHP_POLL_ERROR_CODE_SYSTEM, /* Generic system error */ |
| 68 | + PHP_POLL_ERR_NOMEM = PHP_POLL_ERROR_CODE_NOMEM, /* Out of memory (ENOMEM) */ |
| 69 | + PHP_POLL_ERR_INVALID = PHP_POLL_ERROR_CODE_INVALID, /* Invalid argument (EINVAL, EBADF) */ |
| 70 | + PHP_POLL_ERR_EXISTS = PHP_POLL_ERROR_CODE_EXISTS, /* Already exists (EEXIST) */ |
| 71 | + PHP_POLL_ERR_NOTFOUND = PHP_POLL_ERROR_CODE_NOTFOUND, /* Not found (ENOENT) */ |
| 72 | + PHP_POLL_ERR_TIMEOUT = PHP_POLL_ERROR_CODE_TIMEOUT, /* Operation timed out (ETIME, ETIMEDOUT) */ |
| 73 | + PHP_POLL_ERR_INTERRUPTED = PHP_POLL_ERROR_CODE_INTERRUPTED, /* Interrupted by signal (EINTR) */ |
| 74 | + PHP_POLL_ERR_PERMISSION = PHP_POLL_ERROR_CODE_PERMISSION, /* Permission denied (EACCES, EPERM) */ |
| 75 | + PHP_POLL_ERR_TOOBIG = PHP_POLL_ERROR_CODE_TOOBIG, /* Too many resources (EMFILE, ENFILE) */ |
| 76 | + PHP_POLL_ERR_AGAIN = PHP_POLL_ERROR_CODE_AGAIN, /* Try again (EAGAIN, EWOULDBLOCK) */ |
| 77 | + PHP_POLL_ERR_NOSUPPORT = PHP_POLL_ERROR_CODE_NOSUPPORT, /* Not supported (ENOSYS, EOPNOTSUPP) */ |
| 78 | +} php_poll_error; |
| 79 | + |
| 80 | +/* clang-format on */ |
| 81 | + |
| 82 | +/* Poll event structure */ |
| 83 | +struct php_poll_event { |
| 84 | + int fd; /* File descriptor */ |
| 85 | + uint32_t events; /* Requested events */ |
| 86 | + uint32_t revents; /* Returned events */ |
| 87 | + void *data; /* User data pointer */ |
| 88 | +}; |
| 89 | + |
| 90 | +/* Forward declarations */ |
| 91 | +typedef struct php_poll_ctx php_poll_ctx; |
| 92 | +typedef struct php_poll_backend_ops php_poll_backend_ops; |
| 93 | +typedef struct php_poll_event php_poll_event; |
| 94 | + |
| 95 | +PHPAPI bool php_poll_is_backend_available(php_poll_backend_type backend); |
| 96 | +PHPAPI bool php_poll_backend_supports_edge_triggering(php_poll_backend_type backend); |
| 97 | + |
| 98 | +PHPAPI php_poll_ctx *php_poll_create(php_poll_backend_type preferred_backend, uint32_t flags); |
| 99 | +PHPAPI php_poll_ctx *php_poll_create_by_name(const char *preferred_backend, uint32_t flags); |
| 100 | + |
| 101 | +PHPAPI zend_result php_poll_set_max_events_hint(php_poll_ctx *ctx, int max_events); |
| 102 | +PHPAPI zend_result php_poll_init(php_poll_ctx *ctx); |
| 103 | +PHPAPI void php_poll_destroy(php_poll_ctx *ctx); |
| 104 | + |
| 105 | +PHPAPI zend_result php_poll_add(php_poll_ctx *ctx, int fd, uint32_t events, void *data); |
| 106 | +PHPAPI zend_result php_poll_modify(php_poll_ctx *ctx, int fd, uint32_t events, void *data); |
| 107 | +PHPAPI zend_result php_poll_remove(php_poll_ctx *ctx, int fd); |
| 108 | + |
| 109 | +PHPAPI int php_poll_wait(php_poll_ctx *ctx, php_poll_event *events, int max_events, |
| 110 | + const struct timespec *timeout); |
| 111 | + |
| 112 | +PHPAPI const char *php_poll_backend_name(php_poll_ctx *ctx); |
| 113 | +PHPAPI php_poll_backend_type php_poll_get_backend_type(php_poll_ctx *ctx); |
| 114 | +PHPAPI bool php_poll_supports_et(php_poll_ctx *ctx); |
| 115 | +PHPAPI php_poll_error php_poll_get_error(php_poll_ctx *ctx); |
| 116 | + |
| 117 | +/* Get suitable max_events for backend */ |
| 118 | +PHPAPI int php_poll_get_suitable_max_events(php_poll_ctx *ctx); |
| 119 | + |
| 120 | +/* Backend registration */ |
| 121 | +PHPAPI void php_poll_register_backends(void); |
| 122 | + |
| 123 | +/* Error string for the error */ |
| 124 | +PHPAPI const char *php_poll_error_string(php_poll_error error); |
| 125 | + |
| 126 | +/* ----- Public extension API ----- */ |
| 127 | + |
| 128 | +typedef struct php_poll_handle_ops php_poll_handle_ops; |
| 129 | +typedef struct php_poll_handle_object php_poll_handle_object; |
| 130 | + |
| 131 | +/* Handle operations structure - extensions can provide their own */ |
| 132 | +struct php_poll_handle_ops { |
| 133 | + /** |
| 134 | + * Get file descriptor for this handle |
| 135 | + * @param handle The handle object |
| 136 | + * @return File descriptor or SOCK_ERR if invalid/not applicable |
| 137 | + */ |
| 138 | + php_socket_t (*get_fd)(php_poll_handle_object *handle); |
| 139 | + |
| 140 | + /** |
| 141 | + * Check if handle is still valid |
| 142 | + * @param handle The handle object |
| 143 | + * @return true if valid, false if invalid |
| 144 | + */ |
| 145 | + int (*is_valid)(php_poll_handle_object *handle); |
| 146 | + |
| 147 | + /** |
| 148 | + * Cleanup handle-specific data |
| 149 | + * @param handle The handle object |
| 150 | + */ |
| 151 | + void (*cleanup)(php_poll_handle_object *handle); |
| 152 | +}; |
| 153 | + |
| 154 | +/* Base poll handle object structure */ |
| 155 | +struct php_poll_handle_object { |
| 156 | + php_poll_handle_ops *ops; |
| 157 | + void *handle_data; |
| 158 | + zend_object std; |
| 159 | +}; |
| 160 | + |
| 161 | +#define PHP_POLL_HANDLE_OBJ_FROM_ZOBJ(obj) \ |
| 162 | + ((php_poll_handle_object *) ((char *) (obj) - XtOffsetOf(php_poll_handle_object, std))) |
| 163 | + |
| 164 | +#define PHP_POLL_HANDLE_OBJ_FROM_ZV(zv) PHP_POLL_HANDLE_OBJ_FROM_ZOBJ(Z_OBJ_P(zv)) |
| 165 | + |
| 166 | +/* Default operations */ |
| 167 | +extern php_poll_handle_ops php_poll_handle_default_ops; |
| 168 | + |
| 169 | +/* Utility functions for extensions */ |
| 170 | +PHPAPI php_poll_handle_object *php_poll_handle_object_create( |
| 171 | + size_t obj_size, zend_class_entry *ce, php_poll_handle_ops *ops); |
| 172 | +PHPAPI void php_poll_handle_object_free(zend_object *obj); |
| 173 | + |
| 174 | +/* Get file descriptor from any poll handle */ |
| 175 | +PHPAPI php_socket_t php_poll_handle_get_fd(php_poll_handle_object *handle); |
| 176 | + |
| 177 | +#endif /* PHP_POLL_H */ |
0 commit comments