diff options
Diffstat (limited to 'src/framework/event/epoll/nstack_epoll_api.c')
-rw-r--r-- | src/framework/event/epoll/nstack_epoll_api.c | 192 |
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; +} |