• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 2023 Brad House
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * SPDX-License-Identifier: MIT
25  */
26 #ifndef __ARES__EVENT_H
27 #define __ARES__EVENT_H
28 
29 #include "ares_setup.h"
30 
31 struct ares_event;
32 typedef struct ares_event ares_event_t;
33 
34 typedef enum {
35   ARES_EVENT_FLAG_NONE  = 0,
36   ARES_EVENT_FLAG_READ  = 1 << 0,
37   ARES_EVENT_FLAG_WRITE = 1 << 1,
38   ARES_EVENT_FLAG_OTHER = 1 << 2
39 } ares_event_flags_t;
40 
41 typedef void (*ares_event_cb_t)(ares_event_thread_t *e, ares_socket_t fd,
42                                 void *data, ares_event_flags_t flags);
43 
44 typedef void (*ares_event_free_data_t)(void *data);
45 
46 typedef void (*ares_event_signal_cb_t)(const ares_event_t *event);
47 
48 struct ares_event {
49   /*! Registered event thread this event is bound to */
50   ares_event_thread_t   *e;
51   /*! Flags to monitor. OTHER is only allowed if the socket is ARES_SOCKET_BAD.
52    */
53   ares_event_flags_t     flags;
54   /*! Callback to be called when event is triggered */
55   ares_event_cb_t        cb;
56   /*! Socket to monitor, allowed to be ARES_SOCKET_BAD if not monitoring a
57    *  socket. */
58   ares_socket_t          fd;
59   /*! Data associated with event handle that will be passed to the callback.
60    *  Typically OS/event subsystem specific data.
61    *  Optional, may be NULL. */
62   /*! Data to be passed to callback. Optional, may be NULL. */
63   void                  *data;
64   /*! When cleaning up the registered event (either when removed or during
65    *  shutdown), this function will be called to clean up the user-supplied
66    *  data. Optional, May be NULL. */
67   ares_event_free_data_t free_data_cb;
68   /*! Callback to call to trigger an event. */
69   ares_event_signal_cb_t signal_cb;
70 };
71 
72 typedef struct {
73   const char *name;
74   ares_bool_t (*init)(ares_event_thread_t *e);
75   void        (*destroy)(ares_event_thread_t *e);
76   ares_bool_t (*event_add)(ares_event_t *event);
77   void        (*event_del)(ares_event_t *event);
78   void        (*event_mod)(ares_event_t *event, ares_event_flags_t new_flags);
79   size_t      (*wait)(ares_event_thread_t *e, unsigned long timeout_ms);
80 } ares_event_sys_t;
81 
82 struct ares_event_thread {
83   /*! Whether the event thread should be online or not.  Checked on every wake
84    *  event before sleeping. */
85   ares_bool_t             isup;
86   /*! Handle to the thread for joining during shutdown */
87   ares__thread_t         *thread;
88   /*! Lock to protect the data contained within the event thread itself */
89   ares__thread_mutex_t   *mutex;
90   /*! Reference to the ares channel, for being able to call things like
91    *  ares_timeout() and ares_process_fd(). */
92   ares_channel_t         *channel;
93   /*! Not-yet-processed event handle updates.  These will get enqueued by a
94    *  thread other than the event thread itself. The event thread will then
95    *  be woken then process these updates itself */
96   ares__llist_t          *ev_updates;
97   /*! Registered event handles. */
98   ares__htable_asvp_t    *ev_handles;
99   /*! Pointer to the event handle which is used to signal and wake the event
100    *  thread itself.  This is needed to be able to do things like update the
101    *  file descriptors being waited on and to wake the event subsystem during
102    *  shutdown */
103   ares_event_t           *ev_signal;
104   /* Event subsystem callbacks */
105   const ares_event_sys_t *ev_sys;
106   /* Event subsystem private data */
107   void                   *ev_sys_data;
108 };
109 
110 /*! Queue an update for the event handle.
111  *
112  *  Will search by the fd passed if not ARES_SOCKET_BAD to find a match and
113  *  perform an update or delete (depending on flags).  Otherwise will add.
114  *  Do not use the event handle returned if its not guaranteed to be an add
115  *  operation.
116  *
117  *  \param[out] event        Event handle. Optional, can be NULL.  This handle
118  *                           will be invalidate quickly if the result of the
119  *                           operation is not an ADD.
120  *  \param[in]  e            pointer to event thread handle
121  *  \param[in]  flags        flags for the event handle.  Use
122  *                           ARES_EVENT_FLAG_NONE if removing a socket from
123  *                           queue (not valid if socket is ARES_SOCKET_BAD).
124  *                           Non-socket events cannot be removed, and must have
125  *                           ARES_EVENT_FLAG_OTHER set.
126  *  \param[in]  cb           Callback to call when
127  *                           event is triggered. Required. Not allowed to be
128  *                           changed, ignored on modification.
129  *  \param[in]  fd           File descriptor/socket to monitor. May
130  *                           be ARES_SOCKET_BAD if not monitoring file
131  *                           descriptor.
132  *  \param[in]  data         Optional. Caller-supplied data to be passed to
133  *                           callback. Only allowed on initial add, cannot be
134  *                           modified later, ignored on modification.
135  *  \param[in]  free_data_cb Optional. Callback to clean up caller-supplied
136  *                           data. Only allowed on initial add, cannot be
137  *                           modified later, ignored on modification.
138  *  \param[in]  signal_cb    Optional. Callback to call to trigger an event.
139  *  \return ARES_SUCCESS on success
140  */
141 ares_status_t ares_event_update(ares_event_t **event, ares_event_thread_t *e,
142                                 ares_event_flags_t flags, ares_event_cb_t cb,
143                                 ares_socket_t fd, void *data,
144                                 ares_event_free_data_t free_data_cb,
145                                 ares_event_signal_cb_t signal_cb);
146 
147 
148 #ifdef HAVE_PIPE
149 ares_event_t *ares_pipeevent_create(ares_event_thread_t *e);
150 #endif
151 
152 #ifdef HAVE_POLL
153 extern const ares_event_sys_t ares_evsys_poll;
154 #endif
155 
156 #ifdef HAVE_KQUEUE
157 extern const ares_event_sys_t ares_evsys_kqueue;
158 #endif
159 
160 #ifdef HAVE_EPOLL
161 extern const ares_event_sys_t ares_evsys_epoll;
162 #endif
163 
164 #ifdef _WIN32
165 extern const ares_event_sys_t ares_evsys_win32;
166 #endif
167 
168 /* All systems have select(), but not all have a way to wake, so we require
169  * pipe() to wake the select() */
170 #ifdef HAVE_PIPE
171 extern const ares_event_sys_t ares_evsys_select;
172 #endif
173 
174 #endif
175