1 /*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 /* clang-format off */
17 #include "preamble.h"
18
s_subscribe_to_io_events(struct aws_event_loop * event_loop,struct aws_io_handle * handle,int events,aws_event_loop_on_event_fn_ptr on_event,void * user_data _ (ghost\\claim (c_event_loop)))19 static int s_subscribe_to_io_events(
20 struct aws_event_loop *event_loop,
21 struct aws_io_handle *handle,
22 int events,
23 aws_event_loop_on_event_fn_ptr on_event, /*< VCC change: fnptr */
24 void *user_data
25 _(ghost \claim(c_event_loop))
26 ) {
27 _(assert \always_by_claim(c_event_loop, event_loop))
28
29 AWS_LOGF_TRACE(AWS_LS_IO_EVENT_LOOP, "id=%p: subscribing to events on fd %d", (void *)event_loop, handle->data.fd);
30 struct epoll_event_data *epoll_event_data = aws_mem_calloc(event_loop->alloc, 1, sizeof(struct epoll_event_data));
31 _(unwrap handle)
32 handle->additional_data = epoll_event_data;
33
34 if (!epoll_event_data) {
35 return AWS_OP_ERR;
36 }
37
38 struct epoll_loop *epoll_loop = (struct epoll_loop *)event_loop->impl_data;
39 epoll_event_data->alloc = event_loop->alloc;
40 epoll_event_data->user_data = user_data;
41 epoll_event_data->handle = handle;
42 epoll_event_data->on_event = on_event;
43 epoll_event_data->is_subscribed = true;
44
45 /*everyone is always registered for edge-triggered, hang up, remote hang up, errors. */
46 uint32_t event_mask = EPOLLET | EPOLLHUP | EPOLLRDHUP | EPOLLERR;
47
48 if (events & AWS_IO_EVENT_TYPE_READABLE) {
49 event_mask |= EPOLLIN;
50 }
51
52 if (events & AWS_IO_EVENT_TYPE_WRITABLE) {
53 event_mask |= EPOLLOUT;
54 }
55
56 /* this guy is copied by epoll_ctl */
57 /* VCC change: rewrite struct initialization */
58 #if 0
59 struct epoll_event epoll_event = {
60 .data = {.ptr = epoll_event_data},
61 .events = event_mask,
62 };
63 #else
64 struct epoll_event epoll_event;
65 epoll_event.data.ptr = epoll_event_data;
66 epoll_event.events = event_mask;
67 #endif
68
69 if (epoll_ctl(_(by_claim c_event_loop) epoll_loop->epoll_fd, EPOLL_CTL_ADD, handle->data.fd, &epoll_event)) {
70 AWS_LOGF_ERROR(
71 AWS_LS_IO_EVENT_LOOP, "id=%p: failed to subscribe to events on fd %d", (void *)event_loop, handle->data.fd);
72 handle->additional_data = NULL;
73 aws_mem_release(event_loop->alloc, epoll_event_data);
74 return aws_raise_error(AWS_ERROR_SYS_CALL_FAILURE);
75 }
76 _(wrap(handle))
77 _(wrap(&epoll_event_data->cleanup_task.node))
78 _(wrap(&epoll_event_data->cleanup_task.priority_queue_node))
79 _(wrap(&epoll_event_data->cleanup_task))
80 _(wrap(epoll_event_data))
81
82 return AWS_OP_SUCCESS;
83 }
84 /* clang-format on */
85