aboutsummaryrefslogtreecommitdiffstats
path: root/src/adapt
diff options
context:
space:
mode:
Diffstat (limited to 'src/adapt')
-rw-r--r--src/adapt/nstack_dmm_adpt.c250
-rw-r--r--src/adapt/nstack_dmm_adpt.h62
-rw-r--r--src/adapt/nstack_epoll_comm.c1077
-rw-r--r--src/adapt/nstack_rd_mng.c317
-rw-r--r--src/adapt/nstack_rd_mng.h27
-rw-r--r--src/adapt/nstack_share_res.c176
-rw-r--r--src/adapt/nstack_share_res.h66
7 files changed, 1975 insertions, 0 deletions
diff --git a/src/adapt/nstack_dmm_adpt.c b/src/adapt/nstack_dmm_adpt.c
new file mode 100644
index 0000000..eea2bf1
--- /dev/null
+++ b/src/adapt/nstack_dmm_adpt.c
@@ -0,0 +1,250 @@
+/*
+*
+* 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.
+*/
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#include "nsfw_init.h"
+#include "nsfw_mem_api.h"
+#include "nsfw_recycle_api.h"
+#include "nsfw_mgr_com_api.h"
+#include "nsfw_ps_mem_api.h"
+#include "nsfw_ps_api.h"
+#include "nsfw_recycle_api.h"
+#include "nsfw_fd_timer_api.h"
+#include "nsfw_maintain_api.h"
+#include "nstack_eventpoll.h"
+#include "nstack_dmm_api.h"
+#include "nstack_dmm_adpt.h"
+#include "nstack_rd_mng.h"
+#include "mgr_com.h"
+
+int g_same_process = 1;
+
+extern int nsep_adpt_attach_memory ();
+extern int nstack_init_share_res ();
+extern int nstack_attach_share_res ();
+extern int nsep_adpt_reg_res_mgr ();
+
+/**
+ * This just for linux kernel epoll thread
+ */
+int
+nstack_event_callback (void *pdata, int events)
+{
+ nsep_epollInfo_t *epInfo = (nsep_epollInfo_t *) pdata;
+
+ if (!epInfo)
+ {
+ NSSOC_LOGWAR ("!!!!!!!err pdata=%p,get null epInfo", pdata);
+ return -1;
+ }
+#if 0
+ if (epInfo->rmidx >= 0 && epInfo->rmidx != modInx)
+ {
+ NSSOC_LOGDBG ("This fd should not issue events");
+ return -1;
+ }
+#endif
+
+ NSSOC_LOGDBG ("Got one event]fd=%d,events=%u", epInfo->fd, events);
+
+ sys_arch_lock_with_pid (&epInfo->epiLock);
+ struct list_node *fdEpiHead =
+ (struct list_node *) ADDR_SHTOL (epInfo->epiList.head);
+ struct list_node *node = (struct list_node *) ADDR_SHTOL (fdEpiHead->next);
+ struct epitem *epi = NULL;
+ struct eventpoll *ep = NULL;
+ while (node)
+ {
+
+ epi = (struct epitem *) ep_list_entry (node, struct epitem, fllink);
+
+ node = (struct list_node *) ADDR_SHTOL (node->next);
+ ep = (struct eventpoll *) ADDR_SHTOL (epi->ep);
+ if (!(epi->event.events & events))
+ continue;
+
+ /*event should not notice other process */
+ if ((ep->pid != get_sys_pid ()) && g_same_process)
+ {
+ continue;
+ }
+
+ sys_arch_lock_with_pid (&ep->lock);
+
+ if (unlikely (ep->ovflist != NSEP_EP_UNACTIVE_PTR))
+ {
+ if (epi->next == NSEP_EP_UNACTIVE_PTR)
+ {
+ epi->next = ep->ovflist;
+ ep->ovflist = (struct epitem *) ADDR_LTOSH (epi);
+ }
+ epi->ovf_revents |= events;
+ NSSOC_LOGDBG ("Add to ovflist]protoFD=%d,event=%d", epInfo->fd,
+ events);
+ goto out_unlock;
+ }
+ if (!EP_HLIST_NODE_LINKED (&epi->rdllink))
+ {
+ ep_hlist_add_tail (&ep->rdlist, &epi->rdllink);
+ sem_post (&ep->waitSem);
+ }
+ epi->revents |= events;
+ out_unlock:
+ sys_sem_s_signal (&ep->lock);
+ }
+ sys_sem_s_signal (&epInfo->epiLock);
+ /* [Remove fdInf->event_sem post] */
+ return 0;
+}
+
+int
+nstack_adpt_init (nstack_dmm_para * para)
+{
+ nsfw_mem_para stinfo = { 0 };
+ i32 init_ret = 0;
+
+ if (!para)
+ {
+ return -1;
+ }
+ stinfo.iargsnum = para->argc;
+ stinfo.pargs = para->argv;
+ stinfo.enflag = para->proc_type;
+ if (para->deploy_type >= NSTACK_MODEL_TYPE1)
+ {
+ g_same_process = 0;
+ }
+
+ nsfw_com_attr_set (para->attr.policy, para->attr.pri);
+
+ (void) nstack_framework_setModuleParam (NSFW_MEM_MGR_MODULE, &stinfo);
+ (void) nstack_framework_setModuleParam (NSFW_MGR_COM_MODULE,
+ (void *) ((u64) para->proc_type));
+ (void) nstack_framework_setModuleParam (NSFW_TIMER_MODULE,
+ (void *) ((u64) para->proc_type));
+ (void) nstack_framework_setModuleParam (NSFW_PS_MODULE,
+ (void *) ((u64) para->proc_type));
+ (void) nstack_framework_setModuleParam (NSFW_PS_MEM_MODULE,
+ (void *) ((u64) para->proc_type));
+ (void) nstack_framework_setModuleParam (NSFW_RECYCLE_MODULE,
+ (void *) ((u64) para->proc_type));
+ (void) nstack_framework_setModuleParam (NSFW_RES_MGR_MODULE,
+ (void *) ((u64) para->proc_type));
+ (void) nstack_framework_setModuleParam (NSFW_SOFT_PARAM_MODULE,
+ (void *) ((u64) para->proc_type));
+ (void) nstack_framework_setModuleParam (NSFW_LOG_CFG_MODULE,
+ (void *) ((u64) para->proc_type));
+
+ init_ret = nstack_framework_init ();
+ if (init_ret < 0)
+ {
+ NSFW_LOGERR
+ ("######################init failed!!!!######################");
+ return -1;
+ }
+
+ if ((para->proc_type != NSFW_PROC_APP)
+ && (para->proc_type != NSFW_PROC_MAIN))
+ {
+ return 0;
+ }
+
+ if (para->proc_type == NSFW_PROC_MAIN)
+ {
+ if (nstack_init_share_res () != 0)
+ {
+ NSFW_LOGERR ("nstack_init_share_res failed");
+ return -1;
+ }
+ if (nsep_create_memory () != 0)
+ {
+ NSFW_LOGERR ("nsep_create_memory failed");
+ return -1;
+ }
+
+ if (nstack_rd_mng_int (0) != 0)
+ {
+ NSFW_LOGERR ("nstack_rd_mng_int failed");
+ return -1;
+ }
+ }
+ else
+ {
+ if (nstack_attach_share_res () != 0)
+ {
+ NSFW_LOGERR ("nstack_attach_share_res failed");
+ return -1;
+ }
+
+ /**
+ * the share memory for epoll is created and usedy be app, don't clear
+ * it in fault case.
+ */
+ if (0 != nsep_adpt_attach_memory ())
+ {
+ NSFW_LOGERR ("nsep_adpt_attach_memory failed");
+ return -1;
+ }
+
+ if (nstack_rd_mng_int (1) != 0)
+ {
+ NSFW_LOGERR ("nstack_rd_mng_int failed");
+ return -1;
+ }
+ }
+
+ void *pret =
+ nsfw_recycle_reg_obj (NSFW_REC_PRO_LOWEST, NSFW_REC_NSOCKET_EPOLL,
+ NULL);
+ if (!pret)
+ {
+ NSFW_LOGERR ("regist recycle failed");
+ return -1;
+ }
+ (void) nsep_adpt_reg_res_mgr ();
+
+ return 0;
+}
+
+/*just to used to dependence by other module*/
+int
+nstack_init_module (void *para)
+{
+ return 0;
+}
+
+NSFW_MODULE_NAME (NSTACK_DMM_MODULE)
+NSFW_MODULE_PRIORITY (10)
+NSFW_MODULE_DEPENDS (NSFW_MEM_MGR_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_MGR_COM_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_TIMER_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_PS_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_PS_MEM_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_RECYCLE_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_LOG_CFG_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_RES_MGR_MODULE)
+NSFW_MODULE_DEPENDS (NSFW_SOFT_PARAM_MODULE)
+NSFW_MODULE_INIT (nstack_init_module)
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/src/adapt/nstack_dmm_adpt.h b/src/adapt/nstack_dmm_adpt.h
new file mode 100644
index 0000000..e71dce3
--- /dev/null
+++ b/src/adapt/nstack_dmm_adpt.h
@@ -0,0 +1,62 @@
+/*
+*
+* 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.
+*/
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+#ifndef __NSTACK_DMM_ADPT_H__
+#define __NSTACK_DMM_ADPT_H__
+
+typedef enum
+{
+ NSTACK_MODEL_TYPE1 = 1, /*nSocket and stack belong to the same process */
+ NSTACK_MODEL_TYPE2 = 2, /*nSocket and stack belong to different processes,
+ *and nStack don't take care the communication between stack and stack adpt
+ */
+ NSTACK_MODEL_TYPE3 = 3, /*nSocket and stack belong to different processes, and sbr was spplied to communicate whit stack */
+ NSTACK_MODEL_INVALID,
+} nstack_model_deploy_type;
+
+#define NSTACK_DMM_MODULE "nstack_dmm_module"
+
+typedef struct nsfw_com_attr
+{
+ int policy;
+ int pri;
+} nsfw_com_attr;
+
+typedef struct __nstack_dmm_para
+{
+ nstack_model_deploy_type deploy_type;
+ int proc_type;
+ nsfw_com_attr attr;
+ int argc;
+ char **argv;
+} nstack_dmm_para;
+
+extern int nstack_adpt_init (nstack_dmm_para * para);
+extern int nstack_event_callback (void *pdata, int events);
+
+#endif
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/src/adapt/nstack_epoll_comm.c b/src/adapt/nstack_epoll_comm.c
new file mode 100644
index 0000000..1f3fd02
--- /dev/null
+++ b/src/adapt/nstack_epoll_comm.c
@@ -0,0 +1,1077 @@
+/*
+*
+* 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 <stdio.h>
+#include <stdlib.h>
+
+nsep_epollManager_t g_epollMng = {
+ .infoSockMap = NULL,
+};
+
+/*
+ * This function will find the epitem of fd in eventpool ep
+ * This is only used in epoll_ctl add
+ */
+struct epitem *
+nsep_find_ep (struct eventpoll *ep, int fd)
+{
+ struct ep_rb_node *rbp;
+ struct epitem *epi, *epir = NULL;
+ u32_t loopCnt = 0;
+ for (rbp = ADDR_SHTOL (ep->rbr.rb_node); rbp;)
+ {
+ ++loopCnt;
+ if (loopCnt > NSTACK_MAX_EPITEM_NUM)
+ break;
+
+ epi = (struct epitem *) ep_rb_entry (rbp, struct epitem, rbn);
+ if (fd > epi->fd)
+ {
+ rbp = (struct ep_rb_node *) ADDR_SHTOL (rbp->rb_right);
+ }
+ else if (fd < epi->fd)
+ {
+ rbp = (struct ep_rb_node *) ADDR_SHTOL (rbp->rb_left);
+ }
+ else
+ {
+ epir = epi;
+ break;
+ }
+ }
+
+ if (loopCnt > NSTACK_MAX_EPITEM_NUM)
+ {
+ NSSOC_LOGERR ("Loop out of range!!!!");
+ }
+
+ return epir;
+}
+
+int
+nstack_ep_unlink (struct eventpoll *ep, struct epitem *epi)
+{
+ int error = ENOENT;
+
+ if (ep_rb_parent (&epi->rbn) ==
+ (struct ep_rb_node *) ADDR_LTOSH_EXT (&epi->rbn))
+ {
+ NSSOC_LOGWAR ("ep_rb_parent == epi->rbn");
+ return error;
+ }
+
+ epi->event.events = 0;
+
+ ep_rb_erase (&epi->rbn, &ep->rbr);
+ ep_rb_set_parent (&epi->rbn, &epi->rbn);
+
+ if (EP_HLIST_NODE_LINKED (&epi->rdllink))
+ {
+ ep_hlist_del (&ep->rdlist, &epi->rdllink);
+ }
+
+ return 0;
+}
+
+/**
+ * @Function nsep_free_epitem
+ * @Description free nstack epitem
+ * @param in data - the epitem to be free
+ * @return 0 on success, -1 on error
+ */
+int
+nsep_free_epitem (struct epitem *data)
+{
+ struct epitem *epiEntry = (struct epitem *) data;
+ struct epitem_pool *pool = &nsep_getManager ()->epitemPool;
+ epiEntry->pid = 0;
+ NSSOC_LOGDBG ("nsep_free_epitem data:%p", data);
+ if (res_free (&epiEntry->res_chk))
+ {
+ NSFW_LOGERR ("epitem refree!]epitem=%p", epiEntry);
+ return 0;
+ }
+
+ if (nsfw_mem_ring_enqueue (pool->ring, (void *) epiEntry) != 1)
+ {
+ NSSOC_LOGERR ("Error to free epitem");
+ }
+ return 0;
+}
+
+NSTACK_STATIC void
+nsep_initEpInfo (nsep_epollInfo_t * info)
+{
+ int iindex = 0;
+ EP_LIST_INIT (&info->epiList);
+ NSTACK_SEM_MALLOC (info->epiLock, 1);
+ NSTACK_SEM_MALLOC (info->freeLock, 1);
+
+ info->rlfd = -1;
+ info->rmidx = -1;
+ info->fd = -1;
+ info->ep = NULL;
+ info->fdtype = 0;
+ info->private_data = NULL;
+ info->epaddflag = 0;
+ for (iindex = 0; iindex < NSEP_SMOD_MAX; iindex++)
+ {
+ info->protoFD[iindex] = -1;
+ }
+ (void) nsep_for_pidinfo_init (&(info->pidinfo));
+}
+
+NSTACK_STATIC void
+nsep_destroy_epinfo (nsep_epollInfo_t * info)
+{
+ // TODO: Here we need to free the semaphore
+ return;
+}
+
+/**
+ * @Function nstack_eventpoll_allocShareInfo
+ * @Description alloc nstack share info
+ * @param out data - the return value alloced
+ * @return 0 on success, -1 on error
+ */
+int
+nsep_alloc_epinfo (nsep_epollInfo_t ** data)
+{
+ nsep_epollInfo_t *head_info = NULL;
+
+ if (NULL == data)
+ return -1;
+ NSSOC_LOGDBG ("epinfo alloc begin");
+
+ nsep_infoPool_t *pool = &nsep_getManager ()->infoPool;
+ if (0 == nsfw_mem_ring_dequeue (pool->ring, (void *) &head_info)
+ || NULL == head_info)
+ {
+ NSSOC_LOGERR ("epinfo ring alloc failed]pool->ring=%p", pool->ring);
+ return -1;
+ }
+
+ res_alloc (&head_info->res_chk);
+
+ nsep_initEpInfo (head_info);
+ if (0 != nsep_add_pid (&head_info->pidinfo, get_sys_pid ()))
+ {
+ NSSOC_LOGERR ("epinfo pid add to headinfo failed]pid=%d,headinfo=%p",
+ get_sys_pid (), head_info);
+ }
+ NSSOC_LOGDBG ("epinfo ring:%p alloc epinfo:%p end", pool->ring, head_info);
+ *data = head_info;
+ return 0;
+}
+
+/**
+ * @Function nstack_eventpoll_freeShareInfo
+ * @Description free nstack share info
+ * @param in info - the info to be free
+ * @return 0 on success, -1 on error
+ */
+int
+nsep_free_epinfo (nsep_epollInfo_t * info)
+{
+
+ if (NULL == info)
+ return -1;
+
+ nsep_infoPool_t *pool = &nsep_getManager ()->infoPool;
+ NSSOC_LOGDBG ("nsep_free_epinfo info:%p, pool->ring:%p", info, pool->ring);
+ nsep_destroy_epinfo (info);
+
+ (void) nsep_for_pidinfo_init (&(info->pidinfo));
+ if (res_free (&info->res_chk))
+ {
+ NSFW_LOGERR ("epinfo refree!]epitem=%p", info);
+ return 0;
+ }
+
+ if (nsfw_mem_ring_enqueue (pool->ring, (void *) info) != 1)
+ {
+ NSSOC_LOGERR ("Errot to free epinfo");
+ }
+
+ return 0;
+}
+
+int
+nsep_force_epinfo_free (void *data)
+{
+ nsep_epollInfo_t *info = data;
+ if (NULL == info)
+ {
+ return FALSE;
+ }
+
+ if (!nsep_is_pid_array_empty (&info->pidinfo))
+ {
+ return FALSE;
+ }
+
+ res_alloc (&info->res_chk);
+ (void) nsep_free_epinfo (info);
+ NSFW_LOGINF ("free epinfo]%p", data);
+ return TRUE;
+}
+
+int
+nsep_force_epitem_free (void *data)
+{
+ struct epitem *item = data;
+ if (NULL == item)
+ {
+ return FALSE;
+ }
+
+ if (0 != item->pid)
+ {
+ return FALSE;
+ }
+
+ res_alloc (&item->res_chk);
+ (void) nsep_free_epitem (item);
+ NSFW_LOGINF ("free epitem]%p", data);
+ return TRUE;
+}
+
+int
+nsep_force_epevent_free (void *data)
+{
+ struct eventpoll *epevent = data;
+ if (NULL == epevent)
+ {
+ return FALSE;
+ }
+
+ if (0 != epevent->pid)
+ {
+ return FALSE;
+ }
+
+ res_alloc (&epevent->res_chk);
+ (void) nsep_free_eventpoll (epevent);
+ NSFW_LOGINF ("free event pool]%p", data);
+ return TRUE;
+}
+
+NSTACK_STATIC int
+nsep_init_eventpoll (struct eventpoll *ep)
+{
+ if (0 != sem_init (&ep->waitSem, 1, 0))
+ {
+ return -1;
+ }
+
+ NSTACK_SEM_MALLOC (ep->lock, 1);
+ NSTACK_SEM_MALLOC (ep->sem, 1);
+
+ EP_HLIST_INIT (&ep->rdlist);
+ ep->ovflist = NSEP_EP_UNACTIVE_PTR;
+ ep->rbr.rb_node = NULL;
+ ep->epfd = -1;
+ return 0;
+}
+
+NSTACK_STATIC void
+nsep_destroy_eventpoll (struct eventpoll *ep)
+{
+ (void) sem_destroy (&ep->waitSem);
+}
+
+/**
+ * @Function nsep_free_eventpoll
+ * @Description free nstack eventpoll
+ * @param in ep - the eventpoll to be free
+ * @return 0 on success, -1 on error
+ */
+int
+nsep_free_eventpoll (struct eventpoll *ep)
+{
+ if (!ep)
+ return -1;
+ struct eventpoll *epEntry = (struct eventpoll *) ep;
+ struct eventpoll_pool *pool = &nsep_getManager ()->epollPool;
+ NSSOC_LOGDBG ("nsep_free_eventpoll ep:%p, epollPool:%p", ep, pool);
+ nsep_destroy_eventpoll (ep);
+ ep->pid = 0;
+ NSSOC_LOGDBG ("Free eventpool");
+ if (res_free (&ep->res_chk))
+ {
+ NSFW_LOGERR ("ep refree!]epitem=%p", epEntry);
+ return 0;
+ }
+
+ if (nsfw_mem_ring_enqueue (pool->ring, epEntry) != 1)
+ {
+ NSSOC_LOGERR ("Errot to free eventpoll");
+ }
+
+ return 0;
+}
+
+/**
+ * @Function nsep_alloc_eventpoll
+ * @Description alloc nstack eventpoll
+ * @param out data - the eventpoll alloced
+ * @return 0 on success, -1 on error
+ */
+int
+nsep_alloc_eventpoll (struct eventpoll **data)
+{
+ struct eventpoll *p_head = NULL;
+ struct eventpoll_pool *pool = &nsep_getManager ()->epollPool;
+
+ NSSOC_LOGDBG ("ring:%p alloc eventpool begin", pool->ring);
+ if (0 == nsfw_mem_ring_dequeue (pool->ring, (void *) &p_head)
+ || NULL == p_head)
+ {
+ NSSOC_LOGERR ("ring alloc eventpool failed]ring=%p", pool->ring);
+ return -1;
+ }
+
+ NSSOC_LOGDBG ("alloc eventpool, pid=%u", get_sys_pid ());
+ res_alloc (&p_head->res_chk);
+ p_head->pid = get_sys_pid ();
+
+ if (0 != nsep_init_eventpoll ((struct eventpoll *) p_head))
+ {
+ NSSOC_LOGERR ("p_head init pid alloc failed]p_head=%p,pid=%d", p_head,
+ get_sys_pid ());
+ (void) nsep_free_eventpoll ((struct eventpoll *) p_head);
+ return -1;
+ }
+
+ NSSOC_LOGDBG ("ring:%p eventpoll:%p alloc eventpool end", pool->ring,
+ p_head);
+ *data = p_head;
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_init_epitem (struct epitem *epi)
+{
+ int retVal;
+ epi->rbn.rb_parent = (struct ep_rb_node *) ADDR_LTOSH_EXT (&epi->rbn);
+ EP_HLIST_INIT_NODE (&epi->rdllink);
+ EP_HLIST_INIT_NODE (&epi->lkFDllink);
+ epi->nwait = 0;
+ epi->ep = NULL;
+ epi->next = NSEP_EP_UNACTIVE_PTR;
+ retVal =
+ MEMSET_S (&epi->event, sizeof (epi->event), 0, sizeof (epi->event));
+ if (EOK != retVal)
+ {
+ NSSOC_LOGERR ("MEMSET_S failed]ret=%d", retVal);
+ return -1;
+ }
+
+ EP_LIST_INIT_NODE (&epi->fllink);
+ epi->revents = 0;
+ epi->ovf_revents = 0;
+ epi->fd = -1;
+ epi->private_data = NULL;
+
+ return 0;
+}
+
+/**
+ * @Function nsep_alloc_epitem
+ * @Description alloc nstack epitem
+ * @param out data - the epitem alloced
+ * @return 0 on success, -1 on error
+ */
+int
+nsep_alloc_epitem (struct epitem **data)
+{
+ struct epitem *p_head_entry = NULL;
+ struct epitem_pool *pool = &nsep_getManager ()->epitemPool;
+
+ NSSOC_LOGDBG ("epitem alloc begin..");
+
+ if (0 == nsfw_mem_ring_dequeue (pool->ring, (void *) &p_head_entry)
+ || NULL == p_head_entry)
+ {
+ NSSOC_LOGERR ("epitem ring alloc failed]ring=%p", pool->ring);
+ return -1;
+ }
+
+ res_alloc (&p_head_entry->res_chk);
+ p_head_entry->pid = get_sys_pid ();
+
+ if (nsep_init_epitem ((struct epitem *) p_head_entry))
+ {
+ (void) nsep_free_epitem ((struct epitem *) p_head_entry);
+ p_head_entry = NULL;
+ NSSOC_LOGERR ("ring epitem init failed]ring=%p,epitem=%p", pool->ring,
+ p_head_entry);
+ return -1;
+ }
+
+ NSSOC_LOGDBG ("epitem alloc success..ring:%p head:%p", pool->ring,
+ p_head_entry);
+ *data = p_head_entry;
+ return 0;
+}
+
+typedef int (*nsep_shem_initFn_t) (void *, size_t);
+
+NSTACK_STATIC int
+nsep_epPoolInit (void *addr, size_t lenth)
+{
+ u32_t pos;
+ int ret;
+
+ NSSOC_LOGDBG ("Start to init eventpoll pool");
+
+ ret = MEMSET_S (addr, lenth, 0, lenth);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret);
+ return -1;
+ }
+ struct eventpoll *pool = (struct eventpoll *) addr;
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->epollPool.pool = pool;
+
+ /* init g_nStackInfo.sockPool->nstack_block_array */
+ for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++)
+ {
+ pool[pos].pid = 0;
+ if (-1 == nsfw_mem_ring_enqueue (manager->epollPool.ring, &pool[pos]))
+ {
+ NSSOC_LOGERR ("init fail to enqueue epitem]pos=%u", pos);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_epitemPoolInit (void *addr, size_t lenth)
+{
+ u32_t pos;
+ int ret;
+
+ NSSOC_LOGDBG ("Start to init epitem pool");
+
+ ret = MEMSET_S (addr, lenth, 0, lenth);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret);
+ return -1;
+ }
+ struct epitem *pool = (struct epitem *) addr;
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->epitemPool.pool = pool;
+
+ /* init g_nStackInfo.sockPool->nstack_block_array */
+ for (pos = 0; pos < NSTACK_MAX_EPITEM_NUM; pos++)
+ {
+ pool[pos].pid = 0;
+ if (-1 == nsfw_mem_ring_enqueue (manager->epitemPool.ring, &pool[pos]))
+ {
+ NSSOC_LOGERR ("init fail to enqueue epitem]pos=%u", pos);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_epInfoPoolInit (void *addr, size_t lenth)
+{
+ u32_t pos;
+ int ret;
+
+ NSSOC_LOGDBG ("shmem info init start");
+
+ ret = MEMSET_S (addr, lenth, 0, lenth);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret);
+ return -1;
+ }
+ nsep_epollInfo_t *pool = (nsep_epollInfo_t *) addr;
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->infoPool.pool = pool;
+
+ /* init g_nStackInfo.sockPool->nstack_block_array */
+ for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++)
+ {
+ if (nsep_for_pidinfo_init (&(pool[pos].pidinfo)))
+ {
+ NSSOC_LOGERR ("pid info init failed]pos=%u", pos);
+ return -1;
+ }
+
+ if (-1 == nsfw_mem_ring_enqueue (manager->infoPool.ring, &pool[pos]))
+ {
+ NSSOC_LOGERR ("init fail to enqueue epInfo]pos=%u", pos);
+ return -1;
+ }
+ }
+
+ NSSOC_LOGDBG ("nstack_shmen_info_init success");
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_create_shmem (size_t length, char *name, nsep_shem_initFn_t initFn)
+{
+ nsfw_mem_zone pmeminfo;
+ mzone_handle phandle;
+ int ret;
+
+ pmeminfo.ireserv = 0;
+ pmeminfo.isocket_id = NSFW_SOCKET_ANY;
+ pmeminfo.lenth = length;
+ ret =
+ STRCPY_S (pmeminfo.stname.aname, sizeof (pmeminfo.stname.aname), name);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("STRCPY_S failed]name=%s,ret=%d", name, ret);
+ return -1;
+ }
+ pmeminfo.stname.entype = NSFW_SHMEM;
+
+ phandle = nsfw_mem_zone_create (&pmeminfo);
+ if (NULL == phandle)
+ {
+ NSSOC_LOGERR ("create nstack epoll memory failed]name=%s", name);
+ return -1;
+ }
+
+ if (0 != initFn ((void *) phandle, length))
+ {
+ NSSOC_LOGERR ("Fail to init memory]name=%s", name);
+ return -1;
+ }
+
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_create_epInfoMem ()
+{
+ nsfw_mem_mring pringinfo;
+ pringinfo.enmptype = NSFW_MRING_MPMC;
+ pringinfo.isocket_id = NSFW_SOCKET_ANY;
+ pringinfo.stname.entype = NSFW_SHMEM;
+ pringinfo.usnum = NSTACK_MAX_EPOLL_INFO_NUM;
+
+ if (-1 ==
+ SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EPINFO_RING_NAME))
+ {
+ NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname);
+ return -1;
+ }
+
+ mring_handle ring_handle = nsfw_mem_ring_create (&pringinfo);
+
+ if (NULL == ring_handle)
+ {
+ NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname);
+ return -1;
+ }
+
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->infoPool.ring = ring_handle;
+
+ return nsep_create_shmem (sizeof (nsep_epollInfo_t) *
+ NSTACK_MAX_EPOLL_INFO_NUM,
+ MP_NSTACK_EPOLL_INFO_NAME, nsep_epInfoPoolInit);
+}
+
+NSTACK_STATIC int
+nsep_adpt_attach_epInfoMem ()
+{
+ nsfw_mem_name name;
+ name.entype = NSFW_SHMEM;
+ name.enowner = NSFW_PROC_MAIN;
+
+ if (-1 ==
+ SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EPINFO_RING_NAME))
+ {
+ NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname);
+ return -1;
+ }
+ mring_handle ring_handle = nsfw_mem_ring_lookup (&name);
+
+ if (NULL == ring_handle)
+ {
+ NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname);
+ return -1;
+ }
+
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->infoPool.ring = ring_handle;
+
+ if (-1 ==
+ SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EPOLL_INFO_NAME))
+ {
+ NSSOC_LOGERR ("SPRINTF_S failed]");
+ return -1;
+ }
+ manager->infoPool.pool = nsfw_mem_zone_lookup (&name);
+ if (NULL == manager->infoPool.pool)
+ {
+ NSSOC_LOGERR ("Error to attach memzone]name=%s",
+ MP_NSTACK_EPOLL_INFO_NAME);
+ return -1;
+ }
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_create_epItemMem ()
+{
+ nsfw_mem_mring pringinfo;
+ pringinfo.enmptype = NSFW_MRING_MPMC;
+ pringinfo.isocket_id = NSFW_SOCKET_ANY;
+ pringinfo.stname.entype = NSFW_SHMEM;
+ pringinfo.usnum = NSTACK_MAX_EPITEM_NUM;
+
+ if (-1 ==
+ SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EPITEM_RING_NAME))
+ {
+ NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname);
+ return -1;
+ }
+
+ mring_handle ring_handle = nsfw_mem_ring_create (&pringinfo);
+
+ if (NULL == ring_handle)
+ {
+ NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname);
+ return -1;
+ }
+
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->epitemPool.ring = ring_handle;
+
+ return nsep_create_shmem (sizeof (struct epitem) * NSTACK_MAX_EPITEM_NUM,
+ MP_NSTACK_EPITEM_POOL, nsep_epitemPoolInit);
+}
+
+NSTACK_STATIC int
+nsep_adpt_attach_epItemMem ()
+{
+ nsfw_mem_name name;
+ name.entype = NSFW_SHMEM;
+ name.enowner = NSFW_PROC_MAIN;
+
+ if (-1 ==
+ SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EPITEM_RING_NAME))
+ {
+ NSSOC_LOGERR ("Error to attach epItemMem]name=%s", name.aname);
+ return -1;
+ }
+
+ mring_handle ring_handle = nsfw_mem_ring_lookup (&name);
+
+ if (NULL == ring_handle)
+ {
+ NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname);
+ return -1;
+ }
+
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->epitemPool.ring = ring_handle;
+
+ if (-1 ==
+ SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EPITEM_POOL))
+ {
+ NSSOC_LOGERR ("SPRINTF_S failed]");
+ return -1;
+ }
+ manager->epitemPool.pool = nsfw_mem_zone_lookup (&name);
+ if (NULL == manager->epitemPool.pool)
+ {
+ NSSOC_LOGERR ("Error to attach memzone]name=%s", MP_NSTACK_EPITEM_POOL);
+ return -1;
+ }
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_create_eventpollMem ()
+{
+ nsfw_mem_mring pringinfo;
+ pringinfo.enmptype = NSFW_MRING_MPMC;
+ pringinfo.isocket_id = NSFW_SOCKET_ANY;
+ pringinfo.stname.entype = NSFW_SHMEM;
+ pringinfo.usnum = NSTACK_MAX_EPOLL_NUM;
+
+ if (-1 ==
+ SPRINTF_S (pringinfo.stname.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EVENTPOOL_RING_NAME))
+ {
+ NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname);
+ return -1;
+ }
+
+ mring_handle ring_handle = nsfw_mem_ring_create (&pringinfo);
+
+ if (NULL == ring_handle)
+ {
+ NSSOC_LOGERR ("Error to create ring]name=%s", pringinfo.stname.aname);
+ return -1;
+ }
+
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->epollPool.ring = ring_handle;
+
+ return nsep_create_shmem (sizeof (struct eventpoll) * NSTACK_MAX_EPOLL_NUM,
+ MP_NSTACK_EVENTPOLL_POOL, nsep_epPoolInit);
+}
+
+NSTACK_STATIC int
+nsep_adpt_attach_eventpollMem ()
+{
+ nsfw_mem_name name;
+ name.entype = NSFW_SHMEM;
+ name.enowner = NSFW_PROC_MAIN;
+
+ if (-1 ==
+ SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EVENTPOOL_RING_NAME))
+ {
+ NSSOC_LOGERR ("Error to attach ring]name=%s", name.aname);
+ return -1;
+ }
+
+ mring_handle ring_handle = nsfw_mem_ring_lookup (&name);
+
+ if (NULL == ring_handle)
+ {
+ NSSOC_LOGERR ("Error to create ring]name=%s", name.aname);
+ return -1;
+ }
+
+ nsep_epollManager_t *manager = nsep_getManager ();
+ manager->epollPool.ring = ring_handle;
+
+ int retVal = SPRINTF_S (name.aname, NSFW_MEM_NAME_LENTH, "%s",
+ MP_NSTACK_EVENTPOLL_POOL);
+ if (-1 == retVal)
+ {
+ NSSOC_LOGERR ("SPRINTF_S faild]ret=%d", retVal);
+ return -1;
+ }
+ manager->epollPool.pool = nsfw_mem_zone_lookup (&name);
+ if (NULL == manager->epollPool.pool)
+ {
+ NSSOC_LOGERR ("Error to attach memzone]name=%s",
+ MP_NSTACK_EVENTPOLL_POOL);
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+nsep_create_memory ()
+{
+ typedef int (*nsep_createMemFunc_t) (void);
+ nsep_createMemFunc_t createFuncs[] = { nsep_create_epInfoMem,
+ nsep_create_epItemMem,
+ nsep_create_eventpollMem
+ };
+
+ int i = 0;
+ for (i = 0;
+ i < (int) (sizeof (createFuncs) / sizeof (nsep_createMemFunc_t)); i++)
+ {
+ if (-1 == createFuncs[i] ())
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+nsep_adpt_attach_memory ()
+{
+ typedef int (*nsep_attachMemFunc_t) (void);
+ nsep_attachMemFunc_t attachFuncs[] = { nsep_adpt_attach_epInfoMem,
+ nsep_adpt_attach_epItemMem,
+ nsep_adpt_attach_eventpollMem
+ };
+
+ int i = 0;
+ for (i = 0;
+ i < (int) (sizeof (attachFuncs) / sizeof (nsep_attachMemFunc_t)); i++)
+ {
+ if (-1 == attachFuncs[i] ())
+ {
+ NSSOC_LOGERR ("mem attach fail]idx=%d", i);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+nsep_adpt_reg_res_mgr ()
+{
+
+ nsep_epollManager_t *manager = nsep_getManager ();
+
+ nsfw_res_scn_cfg scn_cfg_info = { NSFW_RES_SCAN_ARRAY, 90, 3, 16,
+ NSTACK_MAX_EPOLL_INFO_NUM / 128, NSTACK_MAX_EPOLL_INFO_NUM,
+ sizeof (nsep_epollInfo_t),
+ offsetof (nsep_epollInfo_t, res_chk),
+ manager->infoPool.pool,
+ manager->infoPool.ring,
+ nsep_force_epinfo_free
+ };
+
+ nsfw_res_scn_cfg scn_cfg_item = { NSFW_RES_SCAN_ARRAY, 90, 3, 16,
+ NSTACK_MAX_EPITEM_NUM / 128, NSTACK_MAX_EPITEM_NUM,
+ sizeof (struct epitem),
+ offsetof (struct epitem, res_chk),
+ manager->epitemPool.pool,
+ manager->epitemPool.ring,
+ nsep_force_epitem_free
+ };
+
+ nsfw_res_scn_cfg scn_cfg_event = { NSFW_RES_SCAN_ARRAY, 90, 3, 16,
+ NSTACK_MAX_EPOLL_NUM / 128, NSTACK_MAX_EPOLL_NUM,
+ sizeof (struct eventpoll),
+ offsetof (struct eventpoll, res_chk),
+ manager->epollPool.pool,
+ manager->epollPool.ring,
+ nsep_force_epevent_free
+ };
+
+ (void) nsfw_res_mgr_reg (&scn_cfg_info);
+ (void) nsfw_res_mgr_reg (&scn_cfg_item);
+ (void) nsfw_res_mgr_reg (&scn_cfg_event);
+ return 0;
+}
+
+int
+nsep_epitem_remove (nsep_epollInfo_t * pinfo, u32 pid)
+{
+ struct list_node *prenode = NULL;
+ struct list_node *nextnode = NULL;
+ struct epitem *epi = NULL;
+ u32_t i = 0;
+ int icnt = 0;
+ (void) sys_arch_lock_with_pid (&pinfo->epiLock);
+ /*list head must be not null */
+ prenode = (struct list_node *) ADDR_SHTOL (pinfo->epiList.head);
+ nextnode = (struct list_node *) ADDR_SHTOL (prenode->next);
+ while ((nextnode) && (i++ <= NSTACK_MAX_EPOLL_INFO_NUM))
+ {
+ epi = ep_list_entry (nextnode, struct epitem, fllink);
+ if (pid == epi->pid)
+ {
+ /*shmem equal to shmem */
+ prenode->next = nextnode->next;
+ nextnode->next = NULL;
+ (void) nsep_free_epitem (epi);
+ nextnode = ADDR_SHTOL (prenode->next);
+ icnt++;
+ continue;
+ }
+ prenode = nextnode;
+ nextnode = ADDR_SHTOL (nextnode->next);
+ }
+ sys_sem_s_signal (&pinfo->epiLock);
+ if (i >= NSTACK_MAX_EPOLL_INFO_NUM)
+ {
+ NSSOC_LOGERR ("free pinfo:%p pid:%u, error maybe happen", pinfo, pid);
+ }
+ return icnt;
+}
+
+void
+nsep_recycle_epfd (void *epinfo, u32 pid)
+{
+ struct eventpoll *ep = NULL;
+ nsep_epollInfo_t *info = (nsep_epollInfo_t *) epinfo;
+ int ret = 0;
+ int ileftcnt = 0;
+ if (!epinfo)
+ {
+ NSSOC_LOGDBG ("input null, pid:%u", pid);
+ return;
+ }
+ (void) sys_arch_lock_with_pid (&info->freeLock);
+ ileftcnt = nsep_del_last_pid (&info->pidinfo, pid);
+ sys_sem_s_signal (&info->freeLock);
+ /*no pid exist */
+ if (-1 == ileftcnt)
+ {
+ return;
+ }
+ if (NSTACK_EPOL_FD == info->fdtype)
+ {
+ NSSOC_LOGDBG ("recycle epfd:%d epinfo pid:%u begin...", info->fd, pid);
+ if (0 == ileftcnt)
+ {
+ ep = ADDR_SHTOL (info->ep);
+ info->ep = NULL;
+ (void) nsep_free_eventpoll (ep);
+ (void) nsep_free_epinfo (info);
+ }
+ return;
+ }
+
+ NSSOC_LOGDBG ("recycle fd:%d epinfo pid:%u begin...", info->fd, pid);
+
+ ret = nsep_epitem_remove (info, pid);
+ if (0 != ret)
+ {
+ NSSOC_LOGINF ("info:%p, fd:%d pid:%u, %d items was left", info,
+ info->fd, pid, ret);
+ }
+
+ if (0 == ileftcnt)
+ {
+ NSSOC_LOGINF ("info:%p, fd:%d pid:%u was finally freed", info, info->fd,
+ pid);
+ (void) nsep_free_epinfo (info);
+ }
+ return;
+}
+
+int
+nsep_recyle_ep (u32 pid)
+{
+ nsep_epollManager_t *manager = nsep_getManager ();
+ nsep_epollInfo_t *pool = manager->infoPool.pool;
+
+ u32_t pos;
+ for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++)
+ {
+ (void) nsep_recycle_epfd (&pool[pos], pid);
+ }
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_recyle_epItem (u32 pid)
+{
+ nsep_epollManager_t *manager = nsep_getManager ();
+ struct epitem *pool = manager->epitemPool.pool;
+
+ u32_t pos;
+ for (pos = 0; pos < NSTACK_MAX_EPITEM_NUM; pos++)
+ {
+ if (pool[pos].pid != pid)
+ continue;
+
+ if (-1 == nsep_free_epitem (&pool[pos]))
+ return -1;
+ }
+
+ return 0;
+}
+
+NSTACK_STATIC int
+nsep_recyle_eventpoll (u32 pid)
+{
+ nsep_epollManager_t *manager = nsep_getManager ();
+ struct eventpoll *pool = manager->epollPool.pool;
+
+ u32_t pos;
+ for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++)
+ {
+ if (pool[pos].pid != pid)
+ continue;
+
+ if (-1 == nsep_free_eventpoll (&pool[pos]))
+ return -1;
+ }
+
+ return 0;
+}
+
+NSTACK_STATIC
+ nsfw_rcc_stat nsep_recycle_resource (u32 exit_pid, void *pdata,
+ u16 rec_type)
+{
+ NSSOC_LOGINF ("pid:%u recycle", exit_pid);
+ (void) nsep_recyle_epItem (exit_pid);
+ (void) nsep_recyle_eventpoll (exit_pid);
+ return NSFW_RCC_CONTINUE;
+}
+
+NSTACK_STATIC
+ nsfw_rcc_stat nsep_recyle_lock (u32 pid, void *pdata, u16 rec_type)
+{
+ nsep_epollManager_t *manager = nsep_getManager ();
+ nsep_epollInfo_t *pool = manager->infoPool.pool;
+ u32_t pos;
+ if (NULL != pool)
+ {
+ for (pos = 0; pos < NSTACK_MAX_EPOLL_INFO_NUM; pos++)
+ {
+ if (pid == pool[pos].epiLock.locked)
+ {
+ pool[pos].epiLock.locked = 0;
+ NSFW_LOGWAR ("epiLock locked]pos=%u,pid=%u", pos, pid);
+ }
+ if (pid == pool[pos].freeLock.locked)
+ {
+ pool[pos].freeLock.locked = 0;
+ NSFW_LOGWAR ("freelock locked]pos=%u,pid=%u", pos, pid);
+ }
+ }
+ }
+
+ struct eventpoll *ev_pool = manager->epollPool.pool;
+ if (NULL != ev_pool)
+ {
+ for (pos = 0; pos < NSTACK_MAX_EPOLL_NUM; pos++)
+ {
+ if (pid == ev_pool[pos].lock.locked)
+ {
+ ev_pool[pos].lock.locked = 0;
+ NSFW_LOGWAR ("event_pollLock locked]pos=%u,pid=%u", pos, pid);
+ }
+
+ if (pid == ev_pool[pos].sem.locked)
+ {
+ ev_pool[pos].sem.locked = 0;
+ NSFW_LOGWAR ("event_pollLock sem]pos=%u,pid=%u", pos, pid);
+ }
+ }
+ }
+
+ return NSFW_RCC_CONTINUE;
+}
+
+REGIST_RECYCLE_OBJ_FUN (NSFW_REC_NSOCKET_EPOLL,
+ nsep_recycle_resource)
+REGIST_RECYCLE_LOCK_REL (nsep_recyle_lock, NULL, NSFW_PROC_NULL)
diff --git a/src/adapt/nstack_rd_mng.c b/src/adapt/nstack_rd_mng.c
new file mode 100644
index 0000000..64c54a8
--- /dev/null
+++ b/src/adapt/nstack_rd_mng.c
@@ -0,0 +1,317 @@
+/*
+*
+* 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 <stdlib.h>
+#include "nstack_rd_data.h"
+#include "nsfw_mem_api.h"
+#include "nstack_log.h"
+#include "nstack_securec.h"
+
+#define RD_SHMEM_NAME "rd_table"
+
+#define RD_AGE_MAX_TIME 3
+
+rd_route_table *g_rd_table_handle = NULL;
+
+#define RD_IP_ROUTE_CPY(pnode, name, data) { \
+ if (EOK != STRCPY_S((pnode)->data.stack_name, RD_PLANE_NAMELEN, (name))) \
+ { \
+ NSSOC_LOGERR("STRCPY_S failed]copy_name=%s", name); \
+ } \
+ (pnode)->data.type = RD_DATA_TYPE_IP; \
+ (pnode)->agetime = 0; \
+ (pnode)->data.ipdata.addr = (data)->addr; \
+ (pnode)->data.ipdata.masklen = (data)->masklen; \
+ (pnode)->data.ipdata.resev[0] = 0; \
+ (pnode)->data.ipdata.resev[1] = 0; \
+}
+
+/*****************************************************************************
+* Prototype : nstack_rd_mng_int
+* Description : rd mng moudule init, create a block memory
+* Input : int flag
+* Output : None
+* Return Value : int
+* Calls :
+* Called By : nStackMain
+*****************************************************************************/
+int
+nstack_rd_mng_int (int flag)
+{
+ int ret;
+ nsfw_mem_zone zname = {
+ {NSFW_SHMEM, NSFW_PROC_MAIN, RD_SHMEM_NAME},
+ sizeof (rd_route_table),
+ NSFW_SOCKET_ANY,
+ 0
+ };
+ NSSOC_LOGINF ("nstack rd mng init begin]flag=%d", flag);
+ /*nstack main create, app lookup */
+ if (0 == flag)
+ {
+ g_rd_table_handle = (rd_route_table *) nsfw_mem_zone_create (&zname);
+ if (!g_rd_table_handle)
+ {
+ NSSOC_LOGERR ("mem create fail]mem name=%s", RD_SHMEM_NAME);
+ return -1;
+ }
+ ret =
+ MEMSET_S (&(g_rd_table_handle->node[0]), sizeof (rd_route_node), 0,
+ sizeof (rd_route_node));
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret);
+ return -1;
+ }
+ g_rd_table_handle->size = NSTACK_RD_DATA_MAX;
+ g_rd_table_handle->icnt = 0;
+ }
+ else /* static data will not be erased in fault case */
+ {
+ g_rd_table_handle =
+ (rd_route_table *) nsfw_mem_zone_lookup (&(zname.stname));
+ if (!g_rd_table_handle)
+ {
+ NSSOC_LOGERR ("mem lookup fail]mem name=%s", RD_SHMEM_NAME);
+ return -1;
+ }
+ }
+ NSSOC_LOGINF ("nstack rd mng init end flag");
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : nstack_rd_ip_node_insert
+* Description : insert a rd_ip_data into list
+* Input : char *name
+* rd_ip_data *data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By : nStackMain
+*****************************************************************************/
+int
+nstack_rd_ip_node_insert (char *name, rd_ip_data * data)
+{
+ if (!g_rd_table_handle)
+ {
+ NSSOC_LOGERR ("nstack rd mng not inited");
+ return -1;
+ }
+ int iindex = 0;
+ rd_route_node *pnode = NULL;
+ int agetime = 0;
+ int ageindex = -1;
+ int freeindex = -1;
+ int repeatflag = 0;
+
+ for (iindex = 0; iindex < NSTACK_RD_DATA_MAX; iindex++)
+ {
+ pnode = &(g_rd_table_handle->node[iindex]);
+ /*record the index of first free element */
+ if (RD_NODE_USELESS == pnode->flag)
+ {
+ if (-1 == freeindex)
+ {
+ freeindex = iindex;
+ NSSOC_LOGINF ("nstack rd ip free element index:%d was found",
+ iindex);
+ }
+ continue;
+ }
+
+ /*if is using, and repeat just set flag */
+ if (RD_NODE_USING == pnode->flag)
+ {
+ if (MASK_V (pnode->data.ipdata.addr, pnode->data.ipdata.masklen) ==
+ MASK_V (data->addr, data->masklen))
+ {
+ NSSOC_LOGWAR
+ ("nstack:%s, old_addr:0x%x index:%d new_addr:0x%x, masklen:%u was repeat",
+ name, pnode->data.ipdata.addr, iindex, data->addr,
+ data->masklen);
+ repeatflag = 1;
+ }
+ continue;
+ }
+
+ /*if flag is deleting, just update the age time, if agetime is on, just set flag to free */
+ if (RD_NODE_DELETING == pnode->flag)
+ {
+ pnode->agetime++;
+ if (pnode->agetime >= RD_AGE_MAX_TIME)
+ {
+ pnode->flag = RD_NODE_USELESS;
+ NSSOC_LOGINF
+ ("nstack rd ip element index:%d addr:0x%x, masklen:%u was delete and set to free",
+ iindex, pnode->data.ipdata.addr, pnode->data.ipdata.masklen);
+ }
+ /*record delete time */
+ if (agetime < pnode->agetime)
+ {
+ agetime = pnode->agetime;
+ ageindex = iindex;
+ }
+ continue;
+ }
+ }
+
+ /*if repeat, just return */
+ if (1 == repeatflag)
+ {
+ return 0;
+ }
+ if (-1 == freeindex)
+ {
+ if (-1 != ageindex)
+ {
+ freeindex = ageindex;
+ }
+ else
+ {
+ NSSOC_LOGERR
+ ("the rd table is full,nstack:%s, rd addr:0x%x, masklen:%u can't be inserted",
+ name, data->addr, data->masklen);
+ return -1;
+ }
+ }
+ pnode = &(g_rd_table_handle->node[freeindex]);
+ /*if no free found, just reuse the big agetime */
+ RD_IP_ROUTE_CPY (pnode, name, data);
+ pnode->flag = RD_NODE_USING; /*last set */
+ g_rd_table_handle->icnt++;
+ NSSOC_LOGINF ("nstack:%s, rd addr:0x%x, masklen:%u index was inserted",
+ name, data->addr, data->masklen);
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : nstack_rd_ip_node_delete
+* Description : rd data delete
+* Input : rd_ip_data *data
+* Output : None
+* Return Value : int
+* Calls :
+* Called By : nStackMain
+* just set delete flag, becuase
+*****************************************************************************/
+int
+nstack_rd_ip_node_delete (rd_ip_data * data)
+{
+ int iindex = 0;
+ rd_route_node *pnode = NULL;
+
+ if (!g_rd_table_handle)
+ {
+ NSSOC_LOGERR ("nstack rd mng not inited");
+ return -1;
+ }
+
+ for (iindex = 0; iindex < NSTACK_RD_DATA_MAX; iindex++)
+ {
+ pnode = &(g_rd_table_handle->node[iindex]);
+ if ((RD_NODE_USING == pnode->flag)
+ && (MASK_V (pnode->data.ipdata.addr, pnode->data.ipdata.masklen) ==
+ MASK_V (data->addr, data->masklen)))
+ {
+ pnode->flag = RD_NODE_DELETING; /*just set deleting state */
+ pnode->agetime = 0;
+ g_rd_table_handle->icnt--;
+ NSSOC_LOGINF
+ ("nstack rd delete:%s, addr:0x%x, masklen:%u index:%d was delete",
+ pnode->data.stack_name, data->addr, data->masklen, iindex);
+ return 0;
+ }
+ }
+ NSSOC_LOGINF ("nstack rd delete, addr:0x%x, masklen:%u index was not found",
+ data->addr, data->masklen);
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : nstack_rd_ip_get
+* Description : get rd data from rd table
+* Input : char *planename
+* rd_route_data **data
+* int *num
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+* Note : a block memory was alloc and return by data,
+* this need free by caller if return 0, otherwise no need
+*****************************************************************************/
+int
+nstack_rd_ip_get (rd_route_data ** data, int *num)
+{
+ rd_route_data *pdata = NULL;
+ rd_route_node *pnode = NULL;
+ int size = 0;
+ int icnt = 0;
+ int idex = 0;
+ int ret;
+
+ if (!g_rd_table_handle || !data || !num)
+ {
+ NSSOC_LOGERR ("nstack rd mng not inited or input err");
+ return -1;
+ }
+ size = sizeof (rd_route_data) * g_rd_table_handle->size;
+ pdata = (rd_route_data *) malloc (size);
+ if (!pdata)
+ {
+ NSSOC_LOGERR ("rd route data malloc fail");
+ return -1;
+ }
+ ret = MEMSET_S (pdata, size, 0, size);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret);
+ free (pdata);
+ return -1;
+ }
+ for (icnt = 0; icnt < g_rd_table_handle->size; icnt++)
+ {
+ pnode = &(g_rd_table_handle->node[icnt]);
+ if (RD_NODE_USING == pnode->flag)
+ {
+ pdata[idex].type = pnode->data.type;
+ pdata[idex].ipdata.addr = pnode->data.ipdata.addr;
+ pdata[idex].ipdata.masklen = pnode->data.ipdata.masklen;
+ pdata[idex].ipdata.resev[0] = pnode->data.ipdata.resev[0];
+ pdata[idex].ipdata.resev[1] = pnode->data.ipdata.resev[1];
+ ret =
+ STRCPY_S (pdata[idex].stack_name, RD_PLANE_NAMELEN,
+ pnode->data.stack_name);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("STRCPY_S failed]ret=%d", ret);
+ free (pdata);
+ return -1;
+ }
+ idex++;
+ }
+ }
+ /*if no data fetched , just return fail */
+ if (idex == 0)
+ {
+ free (pdata);
+ return -1;
+ }
+ *data = pdata;
+ *num = idex;
+ return 0;
+}
diff --git a/src/adapt/nstack_rd_mng.h b/src/adapt/nstack_rd_mng.h
new file mode 100644
index 0000000..f1fe7a3
--- /dev/null
+++ b/src/adapt/nstack_rd_mng.h
@@ -0,0 +1,27 @@
+/*
+*
+* 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.
+*/
+
+#ifndef __NSTACK_RD_MNG_H
+#define __NSTACK_RD_MNG_H
+#include <stdlib.h>
+#include "nstack_rd_data.h"
+
+int nstack_rd_mng_int (int flag);
+int nstack_rd_ip_node_insert (char *name, rd_ip_data * data);
+int nstack_rd_ip_node_delete (rd_ip_data * data);
+int nstack_rd_ip_get (rd_route_data ** data, int *num);
+
+#endif
diff --git a/src/adapt/nstack_share_res.c b/src/adapt/nstack_share_res.c
new file mode 100644
index 0000000..421b5ed
--- /dev/null
+++ b/src/adapt/nstack_share_res.c
@@ -0,0 +1,176 @@
+/*
+*
+* 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_share_res.h"
+#include "nsfw_mem_api.h"
+#include "types.h"
+#include "nsfw_recycle_api.h"
+#include "nstack_securec.h"
+#include "nstack_log.h"
+#include "nsfw_maintain_api.h"
+#include "nstack_types.h"
+
+#define NSTACK_SHARE_FORK_LOCK "share_fork_lock"
+
+typedef struct
+{
+ common_mem_spinlock_t *fork_share_lock;
+} nstack_share_res;
+
+NSTACK_STATIC nstack_share_res g_nstack_share_res;
+
+/** global timer tick */
+nstack_tick_info_t g_nstack_timer_tick;
+
+NSTACK_STATIC int
+nstack_create_share_fork_lock ()
+{
+ mzone_handle zone;
+ nsfw_mem_zone param;
+ int ret;
+
+ param.isocket_id = -1;
+ param.lenth = sizeof (common_mem_spinlock_t);
+ param.stname.entype = NSFW_SHMEM;
+
+ ret =
+ STRCPY_S (param.stname.aname, NSFW_MEM_NAME_LENTH,
+ NSTACK_SHARE_FORK_LOCK);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("STRCPY_S failed]name=%s,ret=%d", NSTACK_SHARE_FORK_LOCK,
+ ret);
+ return -1;
+ }
+
+ zone = nsfw_mem_zone_create (&param);
+ if (!zone)
+ {
+ NSSOC_LOGERR ("nsfw_mem_zone_create failed]name=%s",
+ NSTACK_SHARE_FORK_LOCK);
+ return -1;
+ }
+
+ g_nstack_share_res.fork_share_lock = (common_mem_spinlock_t *) zone;
+ common_mem_spinlock_init (g_nstack_share_res.fork_share_lock);
+
+ NSSOC_LOGDBG ("ok");
+ return 0;
+}
+
+NSTACK_STATIC int
+nstack_lookup_share_fork_lock ()
+{
+ mzone_handle zone;
+ nsfw_mem_name param;
+
+ param.entype = NSFW_SHMEM;
+ param.enowner = NSFW_PROC_MAIN;
+ if (STRCPY_S (param.aname, NSFW_MEM_NAME_LENTH, NSTACK_SHARE_FORK_LOCK) !=
+ 0)
+ {
+ NSSOC_LOGERR ("STRCPY_S failed]name=%s", NSTACK_SHARE_FORK_LOCK);
+ return -1;
+ }
+
+ zone = nsfw_mem_zone_lookup (&param);
+ if (!zone)
+ {
+ NSSOC_LOGERR ("nsfw_mem_zone_lookup failed]name=%s",
+ NSTACK_SHARE_FORK_LOCK);
+ return -1;
+ }
+
+ g_nstack_share_res.fork_share_lock = (common_mem_spinlock_t *) zone;
+
+ NSSOC_LOGDBG ("ok");
+
+ return 0;
+}
+
+NSTACK_STATIC int
+nstack_lookup_share_global_tick ()
+{
+ int ret;
+ nsfw_mem_name name = {.entype = NSFW_SHMEM,.enowner = NSFW_PROC_MAIN };
+
+ ret = STRCPY_S (name.aname, NSFW_MEM_NAME_LENTH, NSTACK_GLOBAL_TICK_SHM);
+ if (EOK != ret)
+ {
+ NSSOC_LOGERR ("STRCPY_S failed]name=%s,ret=%d", NSTACK_GLOBAL_TICK_SHM,
+ ret);
+ return -1;
+ }
+
+ g_nstack_timer_tick.tick_ptr = (u64_t *) nsfw_mem_zone_lookup (&name);
+ if (NULL == g_nstack_timer_tick.tick_ptr)
+ {
+ NSPOL_LOGERR ("Failed to lookup global timer tick memory");
+ return -1;
+ }
+
+ NSSOC_LOGDBG ("ok");
+ return 0;
+}
+
+int
+nstack_init_share_res ()
+{
+ if (nstack_create_share_fork_lock () != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+nstack_attach_share_res ()
+{
+ if (nstack_lookup_share_fork_lock () != 0)
+ {
+ return -1;
+ }
+
+ if (nstack_lookup_share_global_tick () != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+common_mem_spinlock_t *
+nstack_get_fork_share_lock ()
+{
+ return g_nstack_share_res.fork_share_lock;
+}
+
+NSTACK_STATIC nsfw_rcc_stat
+nstack_recycle_fork_share_lock (u32 exit_pid, void *pdata, u16 rec_type)
+{
+ NSSOC_LOGDBG ("recycle]pid=%u", exit_pid);
+
+ if (g_nstack_share_res.fork_share_lock
+ && (g_nstack_share_res.fork_share_lock->locked == exit_pid))
+ {
+ common_mem_spinlock_unlock (g_nstack_share_res.fork_share_lock);
+ }
+
+ return NSFW_RCC_CONTINUE;
+}
+
+REGIST_RECYCLE_LOCK_REL (nstack_recycle_fork_share_lock, NULL, NSFW_PROC_APP)
diff --git a/src/adapt/nstack_share_res.h b/src/adapt/nstack_share_res.h
new file mode 100644
index 0000000..5025482
--- /dev/null
+++ b/src/adapt/nstack_share_res.h
@@ -0,0 +1,66 @@
+/*
+*
+* 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.
+*/
+
+#ifndef NSTACK_SHARE_RES_H
+#define NSTACK_SHARE_RES_H
+
+#include <stdint.h>
+#include "common_mem_spinlock.h"
+#include "nstack_log.h"
+#include "common_func.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define NSTACK_VERSION_SHM "nstack_version"
+#define NSTACK_VERSION_LEN 128
+COMPAT_PROTECT (NSTACK_VERSION_LEN, 128);
+#define MAX_UNMATCH_VER_CNT 32
+COMPAT_PROTECT (MAX_UNMATCH_VER_CNT, 32);
+
+#define NSTACK_GLOBAL_TICK_SHM "nstack_global_tick"
+
+typedef struct unmatch_ver_info
+{
+ int unmatch_count;
+ char lib_version[NSTACK_VERSION_LEN];
+ char first_time_stamp[LOG_TIME_STAMP_LEN];
+} unmatch_ver_info_t;
+
+#define DFX_TMR_INTERVAL 60000 /*60 seconds */
+typedef struct nstack_tick_info
+{
+ uint64_t *tick_ptr; // tick from shared memory
+ uint64_t interval; // tick interval, only used in stack process
+ /* tick refference, updated periodically and read in tcpip_thread only */
+ struct timeval ref_time; // ref tick time
+ uint64_t ref_tick; // ref tick
+} nstack_tick_info_t;
+
+int nstack_init_share_res ();
+int nstack_attach_share_res ();
+common_mem_spinlock_t *nstack_get_fork_share_lock ();
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif