/* * * 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_EVENTPOOL_H #define _NSTACK_EVENTPOOL_H #include "ephlist.h" #include "eprb_tree.h" #include "common_mem_api.h" #include "types.h" #include #include #include #include #include "nstack_securec.h" #include "nstack_log.h" #ifdef __cplusplus /* *INDENT-OFF* */ extern "C"{ /* *INDENT-ON* */ #endif /* __cplusplus */ #define NSTACK_MAX_EPOLL_INFO_NUM 8192 #define NSTACK_MAX_EPOLL_NUM NSTACK_MAX_EPOLL_INFO_NUM #define NSTACK_MAX_EPITEM_NUM (NSTACK_MAX_EPOLL_NUM*2) #define MP_NSTACK_EPOLL_INFO_NAME "nsep_info" #define MP_NSTACK_EVENTPOLL_POOL "nsep_eventpoll" /* Pool of struct eventpoll */ #define MP_NSTACK_EPITEM_POOL "nsep_epitem" /* Pool of struct epitem */ #define MP_NSTACK_EPINFO_RING_NAME "nsep_info_ring" #define MP_NSTACK_EPITEM_RING_NAME "nsep_item_ring" #define MP_NSTACK_EVENTPOOL_RING_NAME "nsep_event_ring" #define NSTACK_FORK_NUM 32 #define NSTACK_EPOL_FD 1 #define NSEP_SMOD_MAX 8 #define NSEP_EP_UNACTIVE_PTR ((void *) -1L) COMPAT_PROTECT (NSEP_SMOD_MAX, 8); typedef struct { u32 pid_used_size; u32 pid_array[NSTACK_FORK_NUM]; } nsep_pidinfo; struct eventpoll { /* * Protect the this structure access * This is for event add to ready list and poll out */ sys_sem_st lock; /* * This semaphore is used to ensure that files are not removed * while epoll is using them. This is read-held during the event * processing loop and it is write-held during the file cleanup * path, the epoll file exit code and the ctl operations. * When we do epoll_ctl, we write lock * When we collecting data , we read lock */ sys_sem_st sem; /* * This sempaphore is used to block epoll_wait function */ sem_t waitSem; /* List of ready file descriptors */ struct ep_hlist rdlist; /* When poll data out, we need this list to store tmp epitems */ struct epitem *ovflist; /* RB-Tree root used to store mastered fd structs */ struct ep_rb_root rbr; /* This specifies the file descriptor value of epoll instance, currenlty it is just used for debugging */ int epfd; u32 pid; nsfw_res res_chk; }; struct eventpoll_pool { void *ring; struct eventpoll *pool; }; typedef struct { int iindex; int iNext; int fd; i32 epaddflag; i32 fdtype; /*0: socket fd, 1: epoll fd */ i32 rlfd; /* copy of fdInf->rlfd */ i32 rmidx; /* copy of fdInf->rmidx */ i32 protoFD[NSEP_SMOD_MAX]; /* copy of fdInf->protoFD */// Here we need to set router infomations dependency struct eventpoll *ep; sys_sem_st epiLock; sys_sem_st freeLock; struct ep_list epiList; /* This restore the epitem of this file descriptor */ u32 sleepTime; //add for NSTACK_SEM_SLEEP nsep_pidinfo pidinfo; nsfw_res res_chk; void *private_data; /*add for degbu, just used to record extern infomation, for example sbr conn */ i32 reserv[4]; } nsep_epollInfo_t; typedef struct { void *ring; nsep_epollInfo_t *pool; char last_reserve[8]; //reserve for update } nsep_infoPool_t; struct epitem { struct ep_rb_node rbn; struct ep_hlist_node rdllink; struct ep_hlist_node lkFDllink; int nwait; struct eventpoll *ep; nsep_epollInfo_t *epInfo; struct epitem *next; struct epoll_event event; struct list_node fllink; unsigned int revents; unsigned int ovf_revents; int fd; u32 pid; void *private_data; nsfw_res res_chk; }; struct epitem_pool { void *ring; struct epitem *pool; }; typedef struct { struct eventpoll_pool epollPool; struct epitem_pool epitemPool; nsep_infoPool_t infoPool; nsep_epollInfo_t **infoSockMap; // The map of epInfo and socket } nsep_epollManager_t; extern nsep_epollManager_t g_epollMng; #define nsep_getManager() (&g_epollMng) extern int nsep_alloc_eventpoll (struct eventpoll **data); extern int nsep_free_eventpoll (struct eventpoll *ep); extern int nsep_alloc_epitem (struct epitem **data); extern int nsep_free_epitem (struct epitem *data); extern int nsep_alloc_epinfo (nsep_epollInfo_t ** data); extern int nsep_free_epinfo (nsep_epollInfo_t * info); extern int nsep_epitem_remove (nsep_epollInfo_t * pinfo, u32 pid); extern struct epitem *nsep_find_ep (struct eventpoll *ep, int fd); extern int nsep_epctl_add (struct eventpoll *ep, int fd, struct epoll_event *events); extern int nsep_epctl_del (struct eventpoll *ep, struct epitem *epi); extern int nsep_epctl_mod (struct eventpoll *ep, nsep_epollInfo_t * epInfo, struct epitem *epi, struct epoll_event *events); extern int nsep_ep_poll (struct eventpoll *ep, struct epoll_event *events, int maxevents, int *eventflag, int num); extern void nsep_remove_epfd (nsep_epollInfo_t * info); extern void nsep_close_epfd (struct eventpoll *ep); /** * @Function nsep_init_infoSockMap * @Description initial map of epoll info and socket * @param none * @return 0 on success, -1 on error */ extern int nsep_init_infoSockMap (); extern void nsep_set_infoSockMap (int sock, nsep_epollInfo_t * info); extern nsep_epollInfo_t *nsep_get_infoBySock (int sock); extern int nsep_alloc_infoWithSock (int nfd); extern void nsep_set_infoProtoFD (int fd, int modInx, int protoFD); extern int nsep_get_infoProtoFD (int fd, int modInx); extern void nsep_set_infomdix (int fd, int rmidx); extern int nsep_get_infoMidx (int fd); extern void nsep_set_infoRlfd (int fd, int rlfd); extern int nsep_get_infoRlfd (int fd); extern void nsep_set_infoSleepTime (int fd, u32 sleepTime); extern int nsep_get_infoSleepTime (int fd); extern void nsep_set_infoEp (int fd, struct eventpoll *ep); extern struct eventpoll *nsep_get_infoEp (int fd); extern int nsep_free_infoWithSock (int sock); extern int nstack_ep_unlink (struct eventpoll *ep, struct epitem *epi); /* Attach shared memory */ extern int nsep_create_memory (); extern int nsep_attach_memory (); extern int nsep_ep_fdinfo_release (int sock); extern int nsep_epoll_close (int sock); extern void nsep_fork_child_proc (u32_t ppid); extern void nsep_fork_parent_proc (u32_t ppid, u32_t cpid); static inline i32 nsep_for_pidinfo_init (nsep_pidinfo * pidinfo) { int ret; ret = MEMSET_S (pidinfo, sizeof (*pidinfo), 0, sizeof (*pidinfo)); if (EOK != ret) { NSSOC_LOGERR ("MEMSET_S failed]ret=%d", ret); return -1; } return 0; } static inline int nsep_add_pid (nsep_pidinfo * pidinfo, pid_t pid) { int i; for (i = 0; i < NSTACK_FORK_NUM; i++) { if ((0 == pidinfo->pid_array[i]) && (__sync_bool_compare_and_swap (&pidinfo->pid_array[i], 0, pid))) { if (pidinfo->pid_used_size < i + 1) { pidinfo->pid_used_size = i + 1; } return 0; } } return -1; } static inline int nsep_del_pid (nsep_pidinfo * pidinfo, pid_t pid) { int i; for (i = 0; i < pidinfo->pid_used_size && i < NSTACK_FORK_NUM; i++) { if (pid == pidinfo->pid_array[i]) { pidinfo->pid_array[i] = 0; return 0; } } return -1; } static inline int nsep_del_last_pid (nsep_pidinfo * pidinfo, pid_t pid) { int i; int count = 0; int deleted = 0; for (i = 0; i < pidinfo->pid_used_size && i < NSTACK_FORK_NUM; i++) { if (pid == pidinfo->pid_array[i]) { pidinfo->pid_array[i] = 0; deleted = 1; continue; } if (pidinfo->pid_array[i] != 0) { ++count; } } if (!deleted) { return -1; } return count; } static inline int nsep_is_pid_exist (nsep_pidinfo * epinf, pid_t pid) { int i; for (i = 0; i < epinf->pid_used_size && i < NSTACK_FORK_NUM; i++) { if (pid == epinf->pid_array[i]) { return 1; } } return 0; } static inline int nsep_is_pid_array_empty (nsep_pidinfo * epinf) { int i; for (i = 0; i < epinf->pid_used_size && i < NSTACK_FORK_NUM; i++) { if (epinf->pid_array[i] != 0) { return 0; } } return 1; } #ifdef __cplusplus /* *INDENT-OFF* */ } /* *INDENT-ON* */ #endif /* __cplusplus */ #endif /* _NSTACK_EVENTPOLL_H */