diff options
Diffstat (limited to 'stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c')
-rw-r--r-- | stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c b/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c new file mode 100644 index 0000000..da62381 --- /dev/null +++ b/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c @@ -0,0 +1,143 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "stackx_epoll_api.h" +#include "stackx_spl_share.h" +#include "common_pal_bitwide_adjust.h" +#include "nstack_dmm_adpt.h" +#include "nstack_epoll_api.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif /* _cplusplus */ + +void epoll_triggle_event_from_api(sbr_socket_t * sock, int op) +{ + struct spl_netconn *conn = sbr_get_conn(sock); + void *epInfo = ADDR_SHTOL(conn->epInfo); + //NSPOL_LOGDBG(SOCKETS_DEBUG, "enter]fd=%d,op=%d", sock, op); + switch (op) + { + case EPOLL_API_OP_RECV: + break; + case EPOLL_API_OP_SEND: + if (conn->epoll_flag && epInfo) + { + NSTACK_EPOLL_EVENT_ADD(epInfo, EPOLLOUT, EVENT_INFORM_APP); + } + break; + case EPOLL_API_OP_STACK_RECV: + if (conn->epoll_flag && epInfo) + { + NSTACK_EPOLL_EVENT_ADD(epInfo, EPOLLIN, EVENT_INFORM_APP); + } + break; + default: + break; + } + return; +} + +/* + * This function will be registed to application + * The context will be in the application + */ +void *stackx_eventpoll_triggle(sbr_socket_t * sock, int triggle_ops, + void *pdata, void *event) +{ + struct spl_netconn *conn = sbr_get_conn(sock); + unsigned int events = 0; + if (!conn) + { + NSPOL_LOGINF(SOCKETS_DEBUG, "get socket failed]fd=%d", sock->fd); + return NULL; + } + + NSPOL_LOGINF(SOCKETS_DEBUG, + "]fd=%d,triggle_ops=%d conn=%p pdata=%p", sock->fd, + triggle_ops, conn, pdata); + /* + * sock->epoll_flag must be set before sock->rcvevent check. + * Consider this Scenario : 1) network stack has got one packet, but event_callback not called yet + * 2) Do epoll ctl add, then stackx triggle will check event, it will get 0 + * 3) network stack call event_callback , it will check epoll_flag + * So, if epoll_flag not set before sock->rcvent check, neither of network stack and stackx triggle + * will add this event to epoll. because : for network stack, event_callback check epoll_flag fail + * for stackx triggle, event check fail. + */ + if (nstack_ep_triggle_add == triggle_ops) + { + /*log info */ + conn->epInfo = pdata; + __sync_fetch_and_add(&conn->epoll_flag, 1); + } + + if ((!((conn->rcvevent == 0) && (sbr_get_fd_share(sock)->lastdata == 0) + && (sbr_get_fd_share(sock)->lastoffset == 0)))) + events |= EPOLLIN; + if (conn->sendevent) + events |= EPOLLOUT; + if (conn->errevent) + events |= conn->errevent; + + switch (triggle_ops) + { + case nstack_ep_triggle_add: + case nstack_ep_triggle_mod: + *(int *) event = events; + break; + case nstack_ep_triggle_del: + if (conn->epoll_flag > 0) + { + __sync_fetch_and_sub(&conn->epoll_flag, 1); + } + events = 0; + break; + default: + return NULL; + } + return conn; +} + +/* + * This function will be registed to application + * The context will be in the application + * RETURN VALUE : Event exists in current protocol + */ +int stackx_eventpoll_getEvt(sbr_socket_t * sock) +{ + struct spl_netconn *conn = sbr_get_conn(sock); + int tevent = 0; + if (!((conn->rcvevent == 0) && (sbr_get_fd_share(sock)->lastdata == 0) + && (sbr_get_fd_share(sock)->lastoffset == 0))) + { + tevent |= EPOLLIN; + } + + if (conn->sendevent) + { + tevent |= EPOLLOUT; + } + return tevent; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* _cplusplus */ |