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