aboutsummaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c
diff options
context:
space:
mode:
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.c150
1 files changed, 150 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..0223ac9
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_epoll_api.c
@@ -0,0 +1,150 @@
+/*
+*
+* 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_dmm_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_event_callback (epInfo, EPOLLOUT);
+ }
+ break;
+ case EPOLL_API_OP_STACK_RECV:
+ if (conn->epoll_flag && epInfo)
+ {
+ nstack_event_callback (epInfo, EPOLLIN);
+ }
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+/*
+ * This function will be registed to application
+ * The context will be in the application
+ */
+unsigned int
+stackx_eventpoll_triggle (sbr_socket_t * sock, int triggle_ops,
+ struct epoll_event *pevent, void *pdata)
+{
+ 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 -1;
+ }
+
+ NSPOL_LOGINF (SOCKETS_DEBUG,
+ "]fd=%d,triggle_ops=%d conn=%p event:%d pdata=%p", sock->fd,
+ triggle_ops, conn, pevent->events, 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 ((pevent->events & EPOLLIN)
+ &&
+ (!((conn->rcvevent == 0) && (sbr_get_fd_share (sock)->lastdata == 0)
+ && (sbr_get_fd_share (sock)->lastoffset == 0))))
+ events |= EPOLLIN;
+ if ((pevent->events & EPOLLOUT) && conn->sendevent)
+ events |= EPOLLOUT;
+ if (conn->errevent)
+ events |= pevent->events & (conn->errevent);
+
+ switch (triggle_ops)
+ {
+ case nstack_ep_triggle_add:
+ break;
+ case nstack_ep_triggle_mod:
+ break;
+ case nstack_ep_triggle_del:
+ if (conn->epoll_flag > 0)
+ {
+ __sync_fetch_and_sub (&conn->epoll_flag, 1);
+ }
+ events = 0;
+ break;
+ default:
+ return -1;
+ }
+ return events;
+}
+
+/*
+ * This function will be registed to application
+ * The context will be in the application
+ * RETURN VALUE : Event exists in current protocol
+ */
+unsigned int
+stackx_eventpoll_getEvt (sbr_socket_t * sock, unsigned int events)
+{
+ struct spl_netconn *conn = sbr_get_conn (sock);
+ unsigned int tevent = 0;
+ if ((events & EPOLLIN)
+ &&
+ (!((conn->rcvevent == 0) && (sbr_get_fd_share (sock)->lastdata == 0)
+ && (sbr_get_fd_share (sock)->lastoffset == 0))))
+ {
+ tevent |= EPOLLIN;
+ }
+
+ if ((events & EPOLLOUT) && conn->sendevent)
+ {
+ tevent |= EPOLLOUT;
+ }
+ return tevent;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* _cplusplus */