summaryrefslogtreecommitdiffstats
path: root/src/framework/event/epoll/nstack_epoll_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/framework/event/epoll/nstack_epoll_api.c')
-rw-r--r--src/framework/event/epoll/nstack_epoll_api.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/src/framework/event/epoll/nstack_epoll_api.c b/src/framework/event/epoll/nstack_epoll_api.c
new file mode 100644
index 0000000..0db6a16
--- /dev/null
+++ b/src/framework/event/epoll/nstack_epoll_api.c
@@ -0,0 +1,192 @@
+/*
+*
+* 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 "nstack_eventpoll.h"
+#include "nsfw_mem_api.h"
+#include "nstack_log.h"
+#include "nstack_securec.h"
+#include "nsfw_recycle_api.h"
+#include "nsfw_maintain_api.h"
+#include "nstack_epoll_api.h"
+#include "nstack_sem.h"
+#include "dmm_spinlock.h"
+#include "nstack_dmm_dfx.h"
+
+extern int nstack_adpt_init(int flag);
+
+i32 nstack_epoll_init(int flag, int ns_sync_mod)
+{
+ i32 ret;
+
+ nstack_adpt_init(flag);
+
+ ret = ns_sync_sem_module_init(flag, ns_sync_mod);
+
+ return ret;
+}
+
+/* add parameter 'postFlag':
+ * 0, do not post ep->waitSem
+ * 1, post ep->waitSem
+ * Support: sometimes APP wants to get all of events generated by one operation
+ * Usage: When multi events continuously reportted, caller need to set postFlag as 1 on the last event.
+ * Note: epif should be local addr.
+***/
+void nstack_epoll_event_enqueue(void *epif, int event, int postFlag)
+{
+ nsep_epollInfo_t *epInfo;
+ mring_handle ring_hd = NULL;
+ struct spl_conn_pool *ep_spl = NULL;
+ u64 rpt_epfd_cnt = 0;
+
+ struct epitem *epi = NULL;
+ struct eventpoll *ep = NULL;
+ int enQueRet;
+ int protoFD;
+ struct list_node *node = NULL;
+ int lock_flag = 0;
+ int retVal = -1;
+ int new_event = 0;
+
+ if (NULL == epif)
+ {
+ return;
+ }
+
+ epInfo = (nsep_epollInfo_t *) (epif);
+ protoFD = epInfo->fd;
+
+ NSFW_LOGDBG("]protoFD=%d,event=%d,postFlag=%d", protoFD, event, postFlag);
+
+ /* solve issue: epoll global lock in daemon-stack
+ cause daemon-stack message handle slowing */
+ /* if this epInfo is from new nstackversion that support ep_conn */
+ if (1 == epInfo->ep_conn_flag)
+ {
+
+ lock_flag =
+ dmm_spin_trylock_with_pid((dmm_spinlock_t *) (&epInfo->epiLock),
+ 0);
+
+ if (0 != lock_flag)
+ {
+ NSFW_LOGINF("not lock]protoFD=%d,event=%d,postFlag=%d,epInfo=%p",
+ protoFD, event, postFlag, epInfo);
+ return;
+ }
+ }
+ else
+ {
+ dmm_spin_lock_with_pid((dmm_spinlock_t *) (&epInfo->epiLock));
+ }
+ struct list_node *fdEpiHead =
+ (struct list_node *) SHMEM_ADDR_SHTOL(epInfo->epiList.head);
+ node = (struct list_node *) SHMEM_ADDR_SHTOL(fdEpiHead->next);
+
+ while (node)
+ {
+ rpt_epfd_cnt++;
+ epi = ep_hlist_entry(node, struct epitem, fllink);
+ node = (struct list_node *) SHMEM_ADDR_SHTOL(node->next);
+
+ ep = (struct eventpoll *) SHMEM_ADDR_SHTOL(epi->ep);
+ if (NULL != epi->ep_spl)
+ {
+ ep_spl = (struct spl_conn_pool *) SHMEM_ADDR_SHTOL(epi->ep_spl);
+ ring_hd = (mring_handle) SHMEM_ADDR_SHTOL(ep_spl->ring_hd);
+ }
+
+ new_event = epi->event.events & event;
+ if ((!new_event) && EVENT_MUST_INFORM_APP != postFlag)
+ {
+ continue;
+ }
+
+ /* solve issue: epoll global lock in daemon-stack
+ cause daemon-stack message handle slowing */
+ /* if it use ep ring */
+
+ NSFW_LOGDBG("]protoFD=%d,event=%d,epi->event.events=%u", protoFD,
+ event, epi->event.events);
+
+ if (NULL != epi->ep_spl)
+ {
+ /* if it is fault restart, then need clear epi from queue firstly */
+ if (EVENT_MUST_INFORM_APP == postFlag)
+ {
+ retVal = nstack_epoll_event_dequeue(epi, 0);
+ }
+
+ epi->revents |= new_event & (EPOLLERR | EPOLLHUP | EPOLLRDHUP);
+ NSFW_LOGDBG("spl_count = %d poll_count = %d",
+ (int) epi->spl_enter_count, epi->app_poll_count);
+ if (((epi->spl_enter_count == epi->app_poll_count)
+ && (EVENT_NO_INFORM_APP != postFlag))
+ || (EVENT_MUST_INFORM_APP == postFlag))
+ {
+ epi->spl_enter_count++;
+ enQueRet = nsfw_mem_ring_enqueue(ring_hd, epi);
+ if (1 != enQueRet)
+ {
+ NSFW_LOGERR
+ ("]ring_hd=%p,spl_enter_count=%u,app_poll_count=%u",
+ ring_hd, epi->spl_enter_count, epi->app_poll_count);
+ dmm_spin_unlock((dmm_spinlock_t *) (&epInfo->epiLock));
+ return;
+ }
+
+ if (-1 == retVal)
+ {
+ nstack_dfx_state_update((u64) epInfo->rlfd, epInfo->rmidx, DMM_MAIN_REPORT_EVENT_TICK, NULL); //need to transform 'event' as pointer to the calling func //Add epoll report stat
+ }
+ NSFW_LOGDBG("protoFD=%d weak up epoll waite renevts = %d",
+ protoFD, epi->revents);
+ g_ns_sync_ops.ns_sync_sem_post(&ep->waitSem); /*do not need return value */
+ }
+
+ continue;
+ }
+
+ dmm_spin_lock_with_pid((dmm_spinlock_t *) (&ep->lock));
+ epi->revents |= new_event;
+ NSFW_LOGDBG("]epi->revents=%u,epi->rdllink=%p", epi->revents,
+ EP_HLIST_NODE_LINKED(&epi->rdllink));
+
+ if (!EP_HLIST_NODE_LINKED(&epi->rdllink)
+ && (EVENT_NO_INFORM_APP != postFlag))
+ {
+ ep_hlist_add_tail(&ep->rdlist, &epi->rdllink);
+ NSFW_LOGDBG("Add to tail]protoFD=%d,event=%d", protoFD, event);
+ nstack_dfx_state_update((u64) epInfo->rlfd, epInfo->rmidx,
+ DMM_MAIN_REPORT_EVENT_TICK, NULL);
+ // SPL_RTI_STAT_MACRO(TYPE_MAIN_REPORT_EVENT_TICK_EPOLL, epInfo->private_data, NULL); //need to transform 'event' as pointer to the calling func //Add epoll report stat
+ g_ns_sync_ops.ns_sync_sem_post(&ep->waitSem); /*do not need return value */
+ }
+ else
+ {
+ NSFW_LOGDBG("No need to add to tail]protoFD=%d,event=%d",
+ protoFD, event);
+ }
+ dmm_spin_unlock((dmm_spinlock_t *) (&ep->lock));
+ }
+
+ nstack_dfx_state_update((u64) epInfo->rlfd, epInfo->rmidx,
+ DMM_MAIN_REPORT_EP_CNT,
+ (void *) (u64) rpt_epfd_cnt);
+ dmm_spin_unlock((dmm_spinlock_t *) (&epInfo->epiLock));
+
+ return;
+}