File: event_loop.h

package info (click to toggle)
aws-crt-python 0.24.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 75,932 kB
  • sloc: ansic: 418,984; python: 23,626; makefile: 6,035; sh: 4,075; ruby: 208; java: 82; perl: 73; cpp: 25; xml: 11
file content (261 lines) | stat: -rw-r--r-- 8,814 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#ifndef AWS_IO_EVENT_LOOP_H
#define AWS_IO_EVENT_LOOP_H

/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#include <aws/io/io.h>

AWS_PUSH_SANE_WARNING_LEVEL

struct aws_event_loop;
struct aws_event_loop_group;
struct aws_event_loop_options;
struct aws_shutdown_callback_options;
struct aws_task;

/**
 * @internal
 */
typedef void(aws_event_loop_on_event_fn)(
    struct aws_event_loop *event_loop,
    struct aws_io_handle *handle,
    int events,
    void *user_data);

/**
 * @internal
 */
struct aws_event_loop_vtable {
    void (*destroy)(struct aws_event_loop *event_loop);
    int (*run)(struct aws_event_loop *event_loop);
    int (*stop)(struct aws_event_loop *event_loop);
    int (*wait_for_stop_completion)(struct aws_event_loop *event_loop);
    void (*schedule_task_now)(struct aws_event_loop *event_loop, struct aws_task *task);
    void (*schedule_task_future)(struct aws_event_loop *event_loop, struct aws_task *task, uint64_t run_at_nanos);
    void (*cancel_task)(struct aws_event_loop *event_loop, struct aws_task *task);
    int (*connect_to_io_completion_port)(struct aws_event_loop *event_loop, struct aws_io_handle *handle);
    int (*subscribe_to_io_events)(
        struct aws_event_loop *event_loop,
        struct aws_io_handle *handle,
        int events,
        aws_event_loop_on_event_fn *on_event,
        void *user_data);
    int (*unsubscribe_from_io_events)(struct aws_event_loop *event_loop, struct aws_io_handle *handle);
    void (*free_io_event_resources)(void *user_data);
    bool (*is_on_callers_thread)(struct aws_event_loop *event_loop);
};

/**
 * Event Loop Type.  If set to `AWS_EVENT_LOOP_PLATFORM_DEFAULT`, the event loop will automatically use the platform’s
 * default.
 *
 * Default Event Loop Type
 * Linux       | AWS_EVENT_LOOP_EPOLL
 * Windows     | AWS_EVENT_LOOP_IOCP
 * BSD Variants| AWS_EVENT_LOOP_KQUEUE
 * macOS       | AWS_EVENT_LOOP_KQUEUE
 * iOS         | AWS_EVENT_LOOP_DISPATCH_QUEUE
 */
enum aws_event_loop_type {
    AWS_EVENT_LOOP_PLATFORM_DEFAULT = 0,
    AWS_EVENT_LOOP_EPOLL,
    AWS_EVENT_LOOP_IOCP,
    AWS_EVENT_LOOP_KQUEUE,
    AWS_EVENT_LOOP_DISPATCH_QUEUE,
};

/**
 * Event loop group configuration options
 */
struct aws_event_loop_group_options {

    /**
     * How many event loops that event loop group should contain.  For most group types, this implies
     * the creation and management of an analagous amount of managed threads
     */
    uint16_t loop_count;

    /**
     * Event loop type. If the event loop type is set to AWS_EVENT_LOOP_PLATFORM_DEFAULT, the
     * creation function will automatically use the platform’s default event loop type.
     */
    enum aws_event_loop_type type;

    /**
     * Optional callback to invoke when the event loop group finishes destruction.
     */
    const struct aws_shutdown_callback_options *shutdown_options;

    /**
     * Optional configuration to control how the event loop group's threads bind to CPU groups
     */
    const uint16_t *cpu_group;

    /**
     * Override for the clock function that event loops should use.  Defaults to the system's high resolution
     * timer.
     *
     * Do not bind this value to managed code; it is only used in timing-sensitive tests.
     */
    aws_io_clock_fn *clock_override;
};

AWS_EXTERN_C_BEGIN

/**
 * The event loop will schedule the task and run it on the event loop thread as soon as possible.
 * Note that cancelled tasks may execute outside the event loop thread.
 * This function may be called from outside or inside the event loop thread.
 *
 * The task should not be cleaned up or modified until its function is executed.
 */
AWS_IO_API
void aws_event_loop_schedule_task_now(struct aws_event_loop *event_loop, struct aws_task *task);

/**
 * The event loop will schedule the task and run it at the specified time.
 * Use aws_event_loop_current_clock_time() to query the current time in nanoseconds.
 * Note that cancelled tasks may execute outside the event loop thread.
 * This function may be called from outside or inside the event loop thread.
 *
 * The task should not be cleaned up or modified until its function is executed.
 */
AWS_IO_API
void aws_event_loop_schedule_task_future(
    struct aws_event_loop *event_loop,
    struct aws_task *task,
    uint64_t run_at_nanos);

/**
 * Cancels task.
 * This function must be called from the event loop's thread, and is only guaranteed
 * to work properly on tasks scheduled from within the event loop's thread.
 * The task will be executed with the AWS_TASK_STATUS_CANCELED status inside this call.
 */
AWS_IO_API
void aws_event_loop_cancel_task(struct aws_event_loop *event_loop, struct aws_task *task);

/**
 * Returns true if the event loop's thread is the same thread that called this function, otherwise false.
 */
AWS_IO_API
bool aws_event_loop_thread_is_callers_thread(struct aws_event_loop *event_loop);

/**
 * Gets the current timestamp for the event loop's clock, in nanoseconds. This function is thread-safe.
 */
AWS_IO_API
int aws_event_loop_current_clock_time(const struct aws_event_loop *event_loop, uint64_t *time_nanos);

/**
 * Creation function for event loop groups.
 */
AWS_IO_API
struct aws_event_loop_group *aws_event_loop_group_new(
    struct aws_allocator *allocator,
    const struct aws_event_loop_group_options *options);

/**
 * Increments the reference count on the event loop group, allowing the caller to take a reference to it.
 *
 * Returns the same event loop group passed in.
 */
AWS_IO_API
struct aws_event_loop_group *aws_event_loop_group_acquire(struct aws_event_loop_group *el_group);

/**
 * Decrements an event loop group's ref count.  When the ref count drops to zero, the event loop group will be
 * destroyed.
 */
AWS_IO_API
void aws_event_loop_group_release(struct aws_event_loop_group *el_group);

/**
 * Returns the event loop at a particular index.  If the index is out of bounds, null is returned.
 */
AWS_IO_API
struct aws_event_loop *aws_event_loop_group_get_loop_at(struct aws_event_loop_group *el_group, size_t index);

/**
 * Gets the number of event loops managed by an event loop group.
 */
AWS_IO_API
size_t aws_event_loop_group_get_loop_count(const struct aws_event_loop_group *el_group);

/**
 * Fetches the next loop for use. The purpose is to enable load balancing across loops. You should not depend on how
 * this load balancing is done as it is subject to change in the future. Currently it uses the "best-of-two" algorithm
 * based on the load factor of each loop.
 */
AWS_IO_API
struct aws_event_loop *aws_event_loop_group_get_next_loop(struct aws_event_loop_group *el_group);

/**
 * @deprecated - use aws_event_loop_group_new() instead
 */
AWS_IO_API
struct aws_event_loop_group *aws_event_loop_group_new_default(
    struct aws_allocator *alloc,
    uint16_t max_threads,
    const struct aws_shutdown_callback_options *shutdown_options);

/**
 * @deprecated - use aws_event_loop_group_new() instead
 */
AWS_IO_API
struct aws_event_loop_group *aws_event_loop_group_new_default_pinned_to_cpu_group(
    struct aws_allocator *alloc,
    uint16_t max_threads,
    uint16_t cpu_group,
    const struct aws_shutdown_callback_options *shutdown_options);

/**
 * @internal - Don't use outside of testing.
 *
 * Returns the opaque internal user data of an event loop.  Can be cast into a specific implementation by
 * privileged consumers.
 */
AWS_IO_API
void *aws_event_loop_get_impl(struct aws_event_loop *event_loop);

/**
 * @internal - Don't use outside of testing.
 *
 * Initializes the base structure used by all event loop implementations with test-oriented overrides.
 */
AWS_IO_API
struct aws_event_loop *aws_event_loop_new_base(
    struct aws_allocator *allocator,
    aws_io_clock_fn *clock,
    struct aws_event_loop_vtable *vtable,
    void *impl);

/**
 * @internal - Don't use outside of testing.
 *
 * Common cleanup code for all implementations.
 * This is only called from the *destroy() function of event loop implementations.
 */
AWS_IO_API
void aws_event_loop_clean_up_base(struct aws_event_loop *event_loop);

/**
 * @internal - Don't use outside of testing.
 *
 * Invokes the destroy() fn for the event loop implementation.
 * If the event loop is still in a running state, this function will block waiting on the event loop to shutdown.
 * If you do not want this function to block, call aws_event_loop_stop() manually first.
 * If the event loop is shared by multiple threads then destroy must be called by exactly one thread. All other threads
 * must ensure their API calls to the event loop happen-before the call to destroy.
 */
AWS_IO_API
void aws_event_loop_destroy(struct aws_event_loop *event_loop);

AWS_EXTERN_C_END

AWS_POP_SANE_WARNING_LEVEL

#endif /* AWS_IO_EVENT_LOOP_H */