diff options
Diffstat (limited to 'src/nSocket/nstack/event/select/nstack_select.c')
-rw-r--r-- | src/nSocket/nstack/event/select/nstack_select.c | 1368 |
1 files changed, 931 insertions, 437 deletions
diff --git a/src/nSocket/nstack/event/select/nstack_select.c b/src/nSocket/nstack/event/select/nstack_select.c index f61b326..b9db0d7 100644 --- a/src/nSocket/nstack/event/select/nstack_select.c +++ b/src/nSocket/nstack/event/select/nstack_select.c @@ -20,220 +20,231 @@ #include "nstack_select.h" #include "nstack_log.h" #include "nsfw_base_linux_api.h" - +#include "nstack.h" +#include "nstack_dmm_dfx.h" /*==============================================* * constants or macros define * *----------------------------------------------*/ #ifdef NSTACK_SELECT_MODULE +#define SELECT_FREE_FD_BITS(read_set, write_set, exp_set) do{\ + select_free((read_set)->fds_bits); \ + select_free((write_set)->fds_bits); \ + select_free((exp_set)->fds_bits); \ +}while(0) /*==============================================* * project-wide global variables * *----------------------------------------------*/ -extern void *nstack_select_thread (void *arg); +extern void *nstack_select_thread(void *arg); +pthread_t g_select_thread_id; /*************select module***************************/ struct select_module_info g_select_module = { - .inited = FALSE, + .inited = FALSE, }; -/*==============================================* - * routines' or functions' implementations * - *----------------------------------------------*/ -/***************************************************************************** -* Prototype : get_select_module -* Description : get_select_module -* Input : void -* Output : None -* Return Value : struct select_module_info * -* Calls : -* Called By : -*****************************************************************************/ -struct select_module_info * -get_select_module (void) +struct select_module_info *get_select_module(void) { - return &g_select_module; + return &g_select_module; } /*split comm seclet entry to child mod select*/ -/***************************************************************************** -* Prototype : select_cb_split_by_mod -* Description : select_cb_split_by_module -* Input : i32 nfds -* fd_set *readfd -* fd_set *writefd -* fd_set *exceptfd -* struct select_entry *entry -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_cb_split_by_mod (i32 nfds, - fd_set * readfd, - fd_set * writefd, - fd_set * exceptfd, struct select_entry * entry) +/*no need to check null pointer*/ + +i32 select_cb_split_by_mod(i32 nfds, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, struct select_entry * entry) { - i32 inx; - i32 i; - i32 fd; + i32 inx; + i32 i; + i32 fd; - for (i = 0; i < nfds; i++) + for (i = 0; i < nfds; i++) { - - /*not bound to any stack */ - for (inx = 0; inx < get_mode_num (); inx++) + /*not bound to any stack */ + for (inx = 0; inx < nstack_get_module_num(); inx++) { - if (!((readfd && FD_ISSET (i, readfd)) || - (writefd && FD_ISSET (i, writefd)) || - (exceptfd && FD_ISSET (i, exceptfd)))) + if (!((readfd && FD_ISSET(i, readfd)) || + (writefd && FD_ISSET(i, writefd)) || + (exceptfd && FD_ISSET(i, exceptfd)))) { - continue; + continue; } - fd = select_get_modfd (i, inx); - /*not create by nstack */ - if ((fd < 0) || (select_get_modindex (i) < 0)) + fd = select_get_modfd(i, inx); + /*not create by nstack */ + if ((fd < 0) || (select_get_modindex(i) < 0)) { - - if (inx != get_mode_linux_index ()) + if (inx != nstack_get_linux_mid()) { - continue; + continue; } - fd = i; - nssct_create (fd, fd, inx); + fd = i; + nssct_create(fd, fd, inx); /*do not need return value */ } - else + else { - if (select_get_modindex (i) != inx) - continue; + if (select_get_modindex(i) != inx) + { + continue; + } } - NSSOC_LOGDBG ("fd is available i= %d fd = %d index = %d\n", i, fd, - inx); - if ((readfd) && (FD_ISSET (i, readfd))) + + NSSOC_LOGDBG("fd is valiable i= %d fd = %d index = %d\n", i, fd, + inx); + if ((readfd) && (FD_ISSET(i, readfd))) { - NSTACK_FD_SET (fd, &(entry->cb[inx].nstack_readset)); - if (entry->cb[inx].count <= fd) - entry->cb[inx].count = fd + 1; + if (inx == nstack_get_linux_mid()) + { + FD_SET(fd, &(entry->cb[inx].readset)); + } + else + { + NSTACK_FD_SET(fd, &(entry->cb[inx].nstack_readset)); + } + if (entry->cb[inx].count <= fd) + { + entry->cb[inx].count = fd + 1; + } } - if ((writefd) && (FD_ISSET (i, writefd))) + if ((writefd) && (FD_ISSET(i, writefd))) { - NSTACK_FD_SET (fd, &(entry->cb[inx].nstack_writeset)); - if (entry->cb[inx].count <= fd) - entry->cb[inx].count = fd + 1; + if (inx == nstack_get_linux_mid()) + { + FD_SET(fd, &(entry->cb[inx].writeset)); + } + else + { + NSTACK_FD_SET(fd, &(entry->cb[inx].nstack_writeset)); + } + + if (entry->cb[inx].count <= fd) + { + entry->cb[inx].count = fd + 1; + } } - if ((exceptfd) && (FD_ISSET (i, exceptfd))) + if ((exceptfd) && (FD_ISSET(i, exceptfd))) { - NSTACK_FD_SET (fd, &(entry->cb[inx].nstack_exceptset)); - if (entry->cb[inx].count <= fd) - entry->cb[inx].count = fd + 1; + if (inx == nstack_get_linux_mid()) + { + FD_SET(fd, &(entry->cb[inx].exceptset)); + } + else + { + NSTACK_FD_SET(fd, &(entry->cb[inx].nstack_exceptset)); + } + + if (entry->cb[inx].count <= fd) + { + entry->cb[inx].count = fd + 1; + } } } } - for (inx = 0; inx < get_mode_num (); inx++) + for (inx = 0; inx < nstack_get_module_num(); inx++) { - if (entry->cb[inx].count > 0) + if (entry->cb[inx].count > 0) { - entry->info.set_num++; - entry->info.index = inx; + entry->info.set_num++; + entry->info.index = inx; } } - return TRUE; + return TRUE; } /***************************************************************************** * Prototype : select_add_cb -* Description : add cb to global list +* Description : add cb to gloab list * Input : struct select_entry *entry * Output : None * Return Value : i32 * Calls : * Called By : *****************************************************************************/ -i32 -select_add_cb (struct select_entry * entry) +i32 select_add_cb(struct select_entry * entry) { - if ((!entry)) + if ((!entry)) { - return FALSE; + return FALSE; } - select_spin_lock (&g_select_module.lock); + select_spin_lock(&g_select_module.lock); - if (!g_select_module.entry_head) + if (!g_select_module.entry_head) { - g_select_module.entry_head = entry; - g_select_module.entry_tail = entry; - entry->next = NULL; - entry->prev = NULL; + g_select_module.entry_head = entry; + g_select_module.entry_tail = entry; + entry->next = NULL; + entry->prev = NULL; } - else + else { - g_select_module.entry_tail->next = entry; - entry->prev = g_select_module.entry_tail; - g_select_module.entry_tail = entry; - entry->next = NULL; + g_select_module.entry_tail->next = entry; + entry->prev = g_select_module.entry_tail; + g_select_module.entry_tail = entry; + entry->next = NULL; } - select_spin_unlock (&g_select_module.lock); - select_sem_post (&g_select_module.sem); - return TRUE; + select_spin_unlock(&g_select_module.lock); + select_sem_post(&g_select_module.sem); /*do not need return value */ + return TRUE; } /***************************************************************************** * Prototype : select_rm_cb -* Description : rm the cb from global list +* Description : rm the cb from gloab list * Input : struct select_entry *entry * Output : None * Return Value : i32 * Calls : * Called By : *****************************************************************************/ -i32 -select_rm_cb (struct select_entry * entry) +i32 select_rm_cb(struct select_entry * entry) { - if (!entry) + if (!entry) { - return FALSE; + return FALSE; } - select_spin_lock (&g_select_module.lock); + select_spin_lock(&g_select_module.lock); - if (g_select_module.entry_head == entry) + if (g_select_module.entry_head == entry) { - g_select_module.entry_head = entry->next; + g_select_module.entry_head = entry->next; } - else if (entry->prev) + else if (entry->prev) { - entry->prev->next = entry->next; + entry->prev->next = entry->next; } - if (g_select_module.entry_tail == entry) + if (g_select_module.entry_tail == entry) { - g_select_module.entry_tail = entry->prev; + g_select_module.entry_tail = entry->prev; } - else if (entry->next) + else if (entry->next) { - entry->next->prev = entry->prev; + entry->next->prev = entry->prev; } - entry->next = NULL; - entry->prev = NULL; + entry->next = NULL; + entry->prev = NULL; - select_spin_unlock (&g_select_module.lock); - return TRUE; + select_spin_unlock(&g_select_module.lock); + return TRUE; } -/*get fd set from entry*/ +/*get fd set from entrys*/ +/*no need to check null pointer*/ /***************************************************************************** * Prototype : select_thread_get_fdset -* Description : get module listening fd form global list +* Description : get module listening fd form gloab list * Input : nstack_fd_set *readfd * nstack_fd_set *writefd * nstack_fd_set *exceptfd @@ -244,55 +255,118 @@ select_rm_cb (struct select_entry * entry) * Calls : * Called By : *****************************************************************************/ -i32 -select_thread_get_fdset (nstack_fd_set * readfd, - nstack_fd_set * writefd, - nstack_fd_set * exceptfd, - struct select_module_info * module, i32 inx) +i32 select_thread_get_fdset(nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, + struct select_module_info * module, i32 inx) { - struct select_entry *tmp; - i32 nfds = 0; - int retVal; + struct select_entry *tmp; + i32 nfds = 0; + int retVal; - if (!module) + if (!module) { - return FALSE; + return FALSE; } - retVal = NSTACK_FD_ZERO (readfd); - retVal |= NSTACK_FD_ZERO (writefd); - retVal |= NSTACK_FD_ZERO (exceptfd); - if (EOK != retVal) + u32 fd_set_size = + sizeof(unsigned char) * ((NSTACK_SELECT_MAX_FD + 7) / 8); + + /*add return value check */ + retVal = NSTACK_FD_ZERO(readfd, fd_set_size); + retVal |= NSTACK_FD_ZERO(writefd, fd_set_size); + retVal |= NSTACK_FD_ZERO(exceptfd, fd_set_size); + if (EOK != retVal) { - NSSOC_LOGERR ("NSTACK_FD_ZERO MEMSET_S failed]ret=%d", retVal); - return FALSE; + NSSOC_LOGERR("NSTACK_FD_ZERO memset_s failed]ret=%d", retVal); + return FALSE; } - select_spin_lock (&module->lock); - for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) { - if (tmp->cb[inx].count <= 0) + if (tmp->cb[inx].count <= 0) { - continue; + continue; } - NSTACK_FD_OR (readfd, &tmp->cb[inx].nstack_readset); - NSTACK_FD_OR (writefd, &tmp->cb[inx].nstack_writeset); - NSTACK_FD_OR (exceptfd, &tmp->cb[inx].nstack_exceptset); - if (nfds < tmp->cb[inx].count) + NSTACK_FD_OR(readfd, &tmp->cb[inx].nstack_readset); + NSTACK_FD_OR(writefd, &tmp->cb[inx].nstack_writeset); + NSTACK_FD_OR(exceptfd, &tmp->cb[inx].nstack_exceptset); + if (nfds < tmp->cb[inx].count) { - nfds = tmp->cb[inx].count; + nfds = tmp->cb[inx].count; } } - select_spin_unlock (&module->lock); + select_spin_unlock(&module->lock); - return nfds; + return nfds; +} + +/*no need to check null pointer*/ + +i32 select_thread_get_fdset_linux(fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, + struct select_module_info * module, i32 inx) +{ + struct select_entry *tmp; + i32 nfds = 0; + int i; + + if (!module) + { + return 0; + } + + FD_ZERO(readfd); + FD_ZERO(writefd); + FD_ZERO(exceptfd); + + select_spin_lock(&module->lock); + + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + { + if (tmp->cb[inx].count <= 0) + { + continue; + } + + /*need to diff linux and daemon-stack */ + for (i = 0; i < __FD_SETSIZE; i++) + { + if (FD_ISSET(i, &tmp->cb[inx].readset)) + { + FD_SET(i, readfd); + } + + if (FD_ISSET(i, &tmp->cb[inx].writeset)) + { + FD_SET(i, writefd); + } + + if (FD_ISSET(i, &tmp->cb[inx].exceptset)) + { + FD_SET(i, exceptfd); + } + } + /*need to diff linux and daemon-stack */ + + if (nfds < tmp->cb[inx].count) + { + nfds = tmp->cb[inx].count; + } + } + + select_spin_unlock(&module->lock); + + return nfds; } /***************************************************************************** * Prototype : select_thread_set_fdset -* Description : set ready event to global list +* Description : set ready event to gloab list * Input : i32 nfds * nstack_fd_set *readfd * nstack_fd_set *writefd @@ -305,186 +379,402 @@ select_thread_get_fdset (nstack_fd_set * readfd, * Calls : * Called By : *****************************************************************************/ -i32 -select_thread_set_fdset (i32 nfds, - nstack_fd_set * readfd, - nstack_fd_set * writefd, - nstack_fd_set * exceptfd, - struct select_module_info * module, i32 inx, i32 err) +i32 select_thread_set_fdset(i32 nfds, + nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, + struct select_module_info * module, + i32 inx, i32 err) { - struct select_entry *tmp; + struct select_entry *tmp; - if (!module) + if (!module) { - return FALSE; + return FALSE; } - select_spin_lock (&module->lock); - for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) { - if (tmp->cb[inx].count <= 0) + if (tmp->cb[inx].count <= 0) { - continue; + continue; } - if (nfds < 0) + if (nfds < 0) { - tmp->ready.readyset = nfds; - tmp->ready.select_errno = err; - continue; + tmp->ready.readyset = nfds; + tmp->ready.select_errno = err; + continue; } - NSSOC_LOGDBG ("readyset=%d,index=%d", tmp->ready.readyset, inx); - entry_module_fdset (tmp, nfds, readfd, writefd, exceptfd, inx); + NSSOC_LOGDBG("readyset=%d,index=%d", tmp->ready.readyset, inx); + entry_module_fdset(tmp, nfds, readfd, writefd, exceptfd, inx); } - select_spin_unlock (&module->lock); - return TRUE; + select_spin_unlock(&module->lock); + return TRUE; } +NSTACK_STATIC inline void entry_mod_fdset_linux(int fd, int idx, int inx, + struct select_entry *entry, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd) +{ + if (FD_ISSET(idx, readfd) && FD_ISSET(idx, &entry->cb[inx].readset)) + { + FD_SET(fd, &entry->ready.readset); + entry->ready.count++; + NSSOC_LOGDBG("readyset is %d", entry->ready.readyset); + } + + if (FD_ISSET(idx, writefd) && FD_ISSET(idx, &entry->cb[inx].writeset)) + { + FD_SET(fd, &entry->ready.writeset); + entry->ready.count++; + NSSOC_LOGDBG("writeset is %d", entry->ready.readyset); + } + + if (FD_ISSET(idx, exceptfd) && FD_ISSET(idx, &entry->cb[inx].exceptset)) + { + FD_SET(fd, &entry->ready.exceptset); + entry->ready.count++; + NSSOC_LOGDBG("exceptset is %d", entry->ready.readyset); + } +} + +NSTACK_STATIC inline void entry_module_fdset_linux(struct select_entry + *entry, i32 fd_size, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, i32 inx) +{ + i32 i; + i32 fd; + + for (i = 0; i < fd_size; i++) + { + fd = select_get_commfd(i, inx); + if (fd < 0) + { + continue; + } + + entry_mod_fdset_linux(fd, i, inx, entry, readfd, writefd, exceptfd); + } +} + +i32 select_thread_set_fdset_linux(i32 nfds, + fd_set * readfd, + fd_set * writefd, + fd_set * exceptfd, + struct select_module_info *module, + i32 inx, i32 err) +{ + + struct select_entry *tmp; + + if (!module) + { + return FALSE; + } + + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + { + if (tmp->cb[inx].count <= 0) + { + continue; + } + + if (nfds < 0) + { + tmp->ready.readyset = nfds; + tmp->ready.select_errno = err; + continue; + } + NSSOC_LOGDBG("readyset=%d,index=%d", tmp->ready.readyset, inx); + entry_module_fdset_linux(tmp, nfds, readfd, writefd, exceptfd, inx); + } + select_spin_unlock(&module->lock); + return TRUE; + +} + +/*no need to check null pointer*/ /***************************************************************************** * Prototype : select_event_post -* Description : when event ready post sem to awake nstack_select +* Description : when event ready post sem to awaik nstack_select * Input : struct select_module_info *module * Output : None * Return Value : void * Calls : * Called By : *****************************************************************************/ -void -select_event_post (struct select_module_info *module) +void select_event_post(struct select_module_info *module) { - struct select_entry *tmp; - int inx; - select_spin_lock (&module->lock); - for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) + struct select_entry *tmp; + int inx; + select_spin_lock(&module->lock); + for (tmp = module->entry_head; NULL != tmp; tmp = tmp->next) { - if ((tmp->ready.readyset != 0)) + if ((tmp->ready.readyset != 0)) { - for (inx = 0; inx < get_mode_num (); inx++) + for (inx = 0; inx < nstack_get_module_num(); inx++) { - tmp->cb[inx].count = 0; + tmp->cb[inx].count = 0; } - NSSOC_LOGDBG ("readyset=%d", tmp->ready.readyset); - select_sem_post (&tmp->sem); + NSSOC_LOGDBG("readyset=%d", tmp->ready.readyset); + select_sem_post(&tmp->sem); /*do not need return value */ } } - select_spin_unlock (&module->lock); + select_spin_unlock(&module->lock); } +/*no need to check null pointer*/ + /*set select_event function*/ -/***************************************************************************** -* Prototype : select_module_init -* Description : init select module -* Input : None -* Output : None -* Return Value : i32 -* Calls : -* Called By : -*****************************************************************************/ -i32 -select_module_init () +i32 select_module_init() { - i32 i; - pthread_t select_thread_id; - i32 retval; + i32 i; + i32 retval; - if (fdmapping_init () < 0) + if (fdmapping_init() < 0) { - goto ERR_RET; + goto ERR_RET; } - g_select_module.default_mod = get_mode_linux_index (); - g_select_module.default_fun = nsfw_base_select; + g_select_module.default_mod = nstack_get_linux_mid(); + g_select_module.default_fun = nsfw_base_select; - /*regist select fun */ - for (i = 0; i < get_mode_num (); i++) + /*regist select fun */ + for (i = 0; i < nstack_get_module_num(); i++) { - g_select_module.get_select_fun_nonblock[i] = - nstack_module_ops (i)->pfselect; + g_select_module.get_select_fun_nonblock[i] = + nstack_module_ops(i)->pfselect; } - select_sem_init (&g_select_module.sem, 0, 0); - select_spin_lock_init (&g_select_module.lock); + select_sem_init(&g_select_module.sem, 0, 0); /*do not need return value */ + select_spin_lock_init(&g_select_module.lock); - if (pthread_create (&select_thread_id, NULL, nstack_select_thread, NULL)) + if (pthread_create(&g_select_thread_id, NULL, nstack_select_thread, NULL)) { - goto ERR_RET; + goto ERR_RET; } - retval = pthread_setname_np (select_thread_id, "nstack_select"); - if (retval) + retval = pthread_setname_np(g_select_thread_id, "nstack_select"); + if (retval) { - /*set thread name failed */ + /*set thread name failed */ } - g_select_module.inited = TRUE; - g_select_module.entry_head = g_select_module.entry_tail = NULL; - return TRUE; + g_select_module.inited = TRUE; + g_select_module.entry_head = g_select_module.entry_tail = NULL; + return TRUE; -ERR_RET: + ERR_RET: - return FALSE; + return FALSE; } -/***************************************************************************** -* Prototype : entry_module_fdset -* Description : set event -* Input : struct select_entry *entry -* i32 fd_size -* nstack_fd_set *readfd -* nstack_fd_set *writefd -* nstack_fd_set *exceptfd -* i32 inx -* Output : None -* Return Value : void -* Calls : -* Called By : -*****************************************************************************/ -void -entry_module_fdset (struct select_entry *entry, - i32 fd_size, - nstack_fd_set * readfd, - nstack_fd_set * writefd, - nstack_fd_set * exceptfd, i32 inx) +NSTACK_STATIC inline void entry_mod_fdset_nstack(int fd, int idx, int inx, + struct select_entry *entry, + nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd) { - i32 i; - i32 fd; + if (NSTACK_FD_ISSET(idx, readfd) + && NSTACK_FD_ISSET(idx, &entry->cb[inx].nstack_readset)) + { + FD_SET(fd, &entry->ready.readset); + entry->ready.count++; + NSSOC_LOGDBG("readyset is %d", entry->ready.readyset); + } - for (i = 0; i < fd_size; i++) + if (NSTACK_FD_ISSET(idx, writefd) + && NSTACK_FD_ISSET(idx, &entry->cb[inx].nstack_writeset)) { - fd = select_get_commfd (i, inx); - if (fd < 0) - { - continue; - } - if (NSTACK_FD_ISSET (i, readfd) - && NSTACK_FD_ISSET (i, &entry->cb[inx].nstack_readset)) - { - FD_SET (fd, &entry->ready.readset); - entry->ready.readyset++; - NSSOC_LOGDBG ("readyset is %d", entry->ready.readyset); - } + FD_SET(fd, &entry->ready.writeset); + entry->ready.count++; + NSSOC_LOGDBG("writeset is %d", entry->ready.readyset); + } - if (NSTACK_FD_ISSET (i, writefd) - && NSTACK_FD_ISSET (i, &entry->cb[inx].nstack_writeset)) - { - FD_SET (fd, &entry->ready.writeset); - entry->ready.readyset++; - NSSOC_LOGDBG ("writeset is %d", entry->ready.readyset); - } + if (NSTACK_FD_ISSET(idx, exceptfd) + && NSTACK_FD_ISSET(idx, &entry->cb[inx].nstack_exceptset)) + { + FD_SET(fd, &entry->ready.exceptset); + entry->ready.count++; + NSSOC_LOGDBG("exceptset is %d", entry->ready.readyset); + } +} - if (NSTACK_FD_ISSET (i, exceptfd) - && NSTACK_FD_ISSET (i, &entry->cb[inx].nstack_exceptset)) +/*no need to check null pointer*/ +void entry_module_fdset(struct select_entry *entry, + i32 fd_size, + nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, i32 inx) +{ + i32 i; + i32 fd; + + for (i = 0; i < fd_size; i++) + { + fd = select_get_commfd(i, inx); + if (fd < 0) { - FD_SET (fd, &entry->ready.exceptset); - entry->ready.readyset++; - NSSOC_LOGDBG ("exceptset is %d", entry->ready.readyset); + continue; } + + entry_mod_fdset_nstack(fd, i, inx, entry, readfd, writefd, exceptfd); } +} +NSTACK_STATIC inline int nstack_fd_copy(nstack_fd_set * psrc, + nstack_fd_set * pdst, u32 size) +{ + return memcpy_s(pdst->fds_bits, size, psrc->fds_bits, size); +} + +NSTACK_STATIC inline int alloc_and_init_fd_set(nstack_fd_set * readfd, + nstack_fd_set * writefd, + nstack_fd_set * exceptfd, + struct select_cb_p *select_cb) +{ + int ret = 0; + u32 fds_bits_size = + sizeof(unsigned char) * ((NSTACK_SELECT_MAX_FD + 7) >> 3); + + readfd->fds_bits = select_fd_set_bits_alloc(); + writefd->fds_bits = select_fd_set_bits_alloc(); + exceptfd->fds_bits = select_fd_set_bits_alloc(); + if (!readfd->fds_bits || !writefd->fds_bits || !exceptfd->fds_bits) + { + return -1; + } + + ret |= + nstack_fd_copy(&(select_cb->nstack_readset), readfd, fds_bits_size); + ret |= + nstack_fd_copy(&(select_cb->nstack_writeset), writefd, fds_bits_size); + ret |= + nstack_fd_copy(&(select_cb->nstack_exceptset), exceptfd, + fds_bits_size); + if (EOK != ret) + { + return -1; + } + + return 0; +} + +NSTACK_STATIC inline i32 select_scan_linux(struct select_entry * entry, + int inx) +{ + i32 fd_size; + i32 ready; + fd_set readfd; + fd_set writefd; + fd_set exceptfd; + struct timeval timeout; + + fd_size = entry->cb[inx].count; + if (!g_select_module.get_select_fun_nonblock[inx] || (fd_size <= 0)) + { + return TRUE; + } + + readfd = (entry->cb[inx].readset); + writefd = (entry->cb[inx].writeset); + exceptfd = (entry->cb[inx].exceptset); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, &readfd, + &writefd, &exceptfd, + &timeout); + if (ready > 0) + { + entry_module_fdset_linux(entry, fd_size, &readfd, &writefd, + &exceptfd, inx); + } + else if (ready < 0) + { + entry->ready.count = ready; + entry->ready.select_errno = errno; + NSSOC_LOGERR("select failed index = %d", inx); + return FALSE; + } + + return TRUE; +} + +NSTACK_STATIC inline i32 select_scan_nstack(struct select_entry * entry, + int inx) +{ + i32 fd_size; + i32 ready; + i32 ret = TRUE; + nstack_fd_set *readfd = NULL; + nstack_fd_set *writefd = NULL; + nstack_fd_set *exceptfd = NULL; + struct timeval timeout; + + fd_size = entry->cb[inx].count; + if (!g_select_module.get_select_fun_nonblock[inx] || (fd_size <= 0)) + { + return TRUE; + } + + readfd = select_alloc(sizeof(nstack_fd_set)); + writefd = select_alloc(sizeof(nstack_fd_set)); + exceptfd = select_alloc(sizeof(nstack_fd_set)); + + if (!readfd || !writefd || !exceptfd) + { + NSSOC_LOGERR("malloc fd sets failed"); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return FALSE; + } + + if (alloc_and_init_fd_set(readfd, writefd, exceptfd, &(entry->cb[inx]))) + { + NSSOC_LOGERR("malloc fd bits failed"); + goto return_over; + ret = FALSE; + } + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, + (fd_set *) readfd, + (fd_set *) writefd, + (fd_set *) exceptfd, + &timeout); + if (ready > 0) + { + entry_module_fdset(entry, fd_size, readfd, writefd, exceptfd, inx); + } + else if (ready < 0) + { + entry->ready.count = ready; + entry->ready.select_errno = errno; + NSSOC_LOGERR("select failed index = %d", inx); + goto return_over; + ret = FALSE; + } + + return_over: + SELECT_FREE_FD_BITS(readfd, writefd, exceptfd); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return ret; } /***************************************************************************** @@ -496,100 +786,37 @@ entry_module_fdset (struct select_entry *entry, * Calls : * Called By : *****************************************************************************/ -i32 -select_scan (struct select_entry *entry) +i32 select_scan(struct select_entry * entry) { - i32 inx; - i32 fd_size; - i32 ready; - nstack_fd_set *readfd; - nstack_fd_set *writefd; - nstack_fd_set *exceptfd; - struct timeval timeout; - - readfd = malloc (sizeof (nstack_fd_set)); - writefd = malloc (sizeof (nstack_fd_set)); - exceptfd = malloc (sizeof (nstack_fd_set)); - if ((!readfd) || (!writefd) || (!exceptfd)) - { - NSPOL_LOGERR ("malloc nstack_fd_set fail"); - FREE_FD_SET (readfd, writefd, exceptfd); - return -1; - } - for (inx = 0; inx < get_mode_num (); inx++) - { - - *readfd = entry->cb[inx].nstack_readset; - *writefd = entry->cb[inx].nstack_writeset; - *exceptfd = entry->cb[inx].nstack_exceptset; - fd_size = entry->cb[inx].count; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - if ((g_select_module.get_select_fun_nonblock[inx]) && (fd_size > 0)) + i32 inx; + int ret = 0; + + for (inx = 0; inx < nstack_get_module_num(); inx++) + { + if (inx == nstack_get_linux_mid()) { - ready = - g_select_module.get_select_fun_nonblock[inx] (fd_size, - (fd_set *) readfd, - (fd_set *) writefd, - (fd_set *) exceptfd, - &timeout); + ret = select_scan_linux(entry, inx); } - else + else { - continue; + ret = select_scan_nstack(entry, inx); } - if (ready > 0) + if (!ret) { - entry_module_fdset (entry, fd_size, readfd, writefd, exceptfd, inx); + return FALSE; } - else if (ready < 0) - { - entry->ready.readyset = ready; - entry->ready.select_errno = errno; - NSSOC_LOGERR ("select failed index = %d", inx); - FREE_FD_SET (readfd, writefd, exceptfd); - return FALSE; - } - } - FREE_FD_SET (readfd, writefd, exceptfd); - return TRUE; -} -/***************************************************************************** -* Prototype : lint_lock -* Description : avoid lint error -* Input : None -* Output : None -* Return Value : static inline void -* Calls : -* Called By : -*****************************************************************************/ -static inline void -lint_lock () -{ - return; + return TRUE; } -/***************************************************************************** -* Prototype : lint_unlock -* Description : avoid lint error -* Input : None -* Output : None -* Return Value : static inline void -* Calls : -* Called By : -*****************************************************************************/ -static inline void -lint_unlock () -{ - return; -} +/*no need to check null pointer*/ +/*try to get event form all modules */ /***************************************************************************** * Prototype : nstack_select_thread -* Description : if global list not null scaning all modules ,need to think +* Description : if gloab list not null scaning all modules ,need to think about block mod * Input : void *arg * Output : None @@ -597,100 +824,145 @@ lint_unlock () * Calls : * Called By : *****************************************************************************/ -void * -nstack_select_thread (void *arg) -{ - -#define SELECT_SLEEP_TIME 100 //us - i32 inx; - nstack_fd_set *readfd; - nstack_fd_set *writefd; - nstack_fd_set *exceptfd; - i32 fd_size; - i32 ready; - i32 sleep_time = SELECT_SLEEP_TIME; - struct timeval timeout; +void *nstack_select_thread(void *arg) +{ - lint_lock (); +#define SELECT_SLEEP_TIME 800 //us + + i32 inx; + nstack_fd_set *readfd; + nstack_fd_set *writefd; + nstack_fd_set *exceptfd; + fd_set rdfd; + fd_set wtfd; + fd_set expfd; + i32 fd_size; + i32 ready; + i32 sleep_time = SELECT_SLEEP_TIME; + struct timeval timeout; + int selet_errno; + + readfd = select_alloc(sizeof(nstack_fd_set)); + writefd = select_alloc(sizeof(nstack_fd_set)); + exceptfd = select_alloc(sizeof(nstack_fd_set)); + if ((!readfd) || (!writefd) || (!exceptfd)) + { + NSPOL_LOGERR("malloc nstack_fd_set fail"); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return NULL; + } - readfd = malloc (sizeof (nstack_fd_set)); - writefd = malloc (sizeof (nstack_fd_set)); - exceptfd = malloc (sizeof (nstack_fd_set)); - if ((!readfd) || (!writefd) || (!exceptfd)) + readfd->fds_bits = select_fd_set_bits_alloc(); + writefd->fds_bits = select_fd_set_bits_alloc(); + exceptfd->fds_bits = select_fd_set_bits_alloc(); + if ((!readfd->fds_bits) || (!writefd->fds_bits) || (!exceptfd->fds_bits)) { - NSPOL_LOGERR ("malloc nstack_fd_set fail"); - FREE_FD_SET (readfd, writefd, exceptfd); - lint_unlock (); - return NULL; + NSPOL_LOGERR("malloc fd_bits for nstack_fd_set fail"); + + SELECT_FREE_FD_BITS(readfd, writefd, exceptfd); + FREE_SELECT_FD_SET(readfd, writefd, exceptfd); + return NULL; } - /*used nonblock need add block mod later */ + /*used nonblock need add block mod later */ - for (;;) + for (;;) { - /*wait app calling select no cong cpu */ - if (!g_select_module.entry_head) + /*wait app calling select no cong cpu */ + if (!g_select_module.entry_head) { - select_sem_wait (&g_select_module.sem); + select_sem_wait(&g_select_module.sem); /*do not need return value */ } - for (inx = 0; inx < get_mode_num (); inx++) + for (inx = 0; inx < nstack_get_module_num(); inx++) { - fd_size = - select_thread_get_fdset (readfd, writefd, exceptfd, - &g_select_module, inx); - if (fd_size <= 0) + if (inx == nstack_get_linux_mid()) { - continue; - } + fd_size = + select_thread_get_fdset_linux(&rdfd, &wtfd, &expfd, + &g_select_module, inx); + if (fd_size <= 0) + continue; + if (g_select_module.get_select_fun_nonblock[inx]) + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, + (fd_set + *) & + rdfd, + (fd_set + *) & + wtfd, + (fd_set + *) & + expfd, + &timeout); + else + continue; + + if (ready > 0) + + select_thread_set_fdset_linux(fd_size, &rdfd, + &wtfd, &expfd, + &g_select_module, inx, 0); + else if (ready < 0) + { - if (g_select_module.get_select_fun_nonblock[inx]) - { - ready = - g_select_module.get_select_fun_nonblock[inx] (fd_size, - (fd_set *) - readfd, - (fd_set *) - writefd, - (fd_set *) - exceptfd, - &timeout); + selet_errno = errno; + select_thread_set_fdset_linux(fd_size, &rdfd, &wtfd, + &expfd, &g_select_module, + inx, selet_errno); + break; + } } - else + else { - continue; - } + fd_size = + select_thread_get_fdset(readfd, writefd, exceptfd, + &g_select_module, inx); + if (fd_size <= 0) + continue; + if (g_select_module.get_select_fun_nonblock[inx]) + ready = + g_select_module.get_select_fun_nonblock[inx] (fd_size, + (fd_set + *) + readfd, + (fd_set + *) + writefd, + (fd_set + *) + exceptfd, + &timeout); + else + continue; + + if (ready > 0) + select_thread_set_fdset(fd_size, readfd, writefd, exceptfd, &g_select_module, inx, 0); /*do not need return value */ + else if (ready < 0) + { + selet_errno = errno; + select_thread_set_fdset(ready, readfd, writefd, exceptfd, &g_select_module, inx, selet_errno); /*do not need return value */ + break; + } - if (ready > 0) - { - select_thread_set_fdset (fd_size, readfd, writefd, exceptfd, - &g_select_module, inx, 0); - } - else if (ready < 0) - { - select_thread_set_fdset (ready, readfd, writefd, exceptfd, - &g_select_module, inx, errno); - NSSOC_LOGERR ("module[%d] select failed] ret = %d errno = %d", - inx, ready, errno); - lint_unlock (); - break; } } - select_event_post (&g_select_module); - timeout.tv_sec = 0; - timeout.tv_usec = sleep_time; - lint_unlock (); - /*use linux select for timer */ - nsfw_base_select (1, NULL, NULL, NULL, &timeout); + select_event_post(&g_select_module); + timeout.tv_sec = 0; + timeout.tv_usec = sleep_time; + /*use linux select for timer */ + nsfw_base_select(1, NULL, NULL, NULL, &timeout); + //sys_sleep_ns(0, sleep_time); //g_sem_sleep_time } } /***************************************************************************** * Prototype : nssct_create -* Description : create a select record for event fd +* Description : create a select record for eveny fd * Input : i32 cfd * i32 mfd * i32 inx @@ -699,15 +971,14 @@ nstack_select_thread (void *arg) * Calls : * Called By : *****************************************************************************/ -void -nssct_create (i32 cfd, i32 mfd, i32 inx) +void nssct_create(i32 cfd, i32 mfd, i32 inx) { - if (g_select_module.inited != TRUE) + if (g_select_module.inited != TRUE) { - return; + return; } - select_set_modfd (cfd, inx, mfd); - select_set_commfd (mfd, inx, cfd); + select_set_modfd(cfd, inx, mfd); /*do not need return value */ + select_set_commfd(mfd, inx, cfd); /*do not need return value */ } /***************************************************************************** @@ -720,17 +991,16 @@ nssct_create (i32 cfd, i32 mfd, i32 inx) * Calls : * Called By : *****************************************************************************/ -void -nssct_close (i32 cfd, i32 inx) +void nssct_close(i32 cfd, i32 inx) { - if (g_select_module.inited != TRUE) + if (g_select_module.inited != TRUE) { - return; + return; } - i32 mfd = select_get_modfd (cfd, inx); - select_set_modfd (cfd, inx, -1); - select_set_commfd (mfd, inx, -1); - select_set_index (cfd, -1); + i32 mfd = select_get_modfd(cfd, inx); + select_set_modfd(cfd, inx, -1); /*do not need return value */ + select_set_commfd(mfd, inx, -1); /*do not need return value */ + select_set_index(cfd, -1); /*do not need return value */ } /***************************************************************************** @@ -743,36 +1013,260 @@ nssct_close (i32 cfd, i32 inx) * Calls : * Called By : *****************************************************************************/ -void -nssct_set_index (i32 fd, i32 inx) +void nssct_set_index(i32 fd, i32 inx) +{ + if (g_select_module.inited != TRUE) + { + return; + } + select_set_index(fd, inx); /*do not need return value */ +} + +int select_scan_return_from_entry(fd_set * readfds, fd_set * writefds, + fd_set * exceptfds, + struct select_entry *entry) +{ + int ret; + if (readfds) + { + *readfds = entry->ready.readset; + } + if (writefds) + { + *writefds = entry->ready.writeset; + } + if (exceptfds) + { + *exceptfds = entry->ready.exceptset; + } + + ret = entry->ready.readyset; + if (ret < 0) + { + errno = entry->ready.select_errno; + } + return ret; +} + +void nstack_select_entry_free(struct select_entry *entry) +{ + int i; + + if (!entry) + return; + + for (i = 0; i < nstack_get_module_num(); i++) + { + + SELECT_FREE_FD_BITS(&entry->cb[i].nstack_readset, + &entry->cb[i].nstack_writeset, + &entry->cb[i].nstack_exceptset); + } + + SELECT_FREE_FD_BITS(&entry->ready.nstack_readset, + &entry->ready.nstack_writeset, + &entry->ready.nstack_exceptset); + +} + +void nstack_select_entry_alloc(struct select_entry **entry) { - if (g_select_module.inited != TRUE) + struct select_entry *tmp; + int i; + + tmp = select_alloc(sizeof(struct select_entry)); + if (!tmp) + return; + for (i = 0; i < nstack_get_module_num(); i++) + { + tmp->cb[i].nstack_readset.fds_bits = select_fd_set_bits_alloc(); + tmp->cb[i].nstack_writeset.fds_bits = select_fd_set_bits_alloc(); + tmp->cb[i].nstack_exceptset.fds_bits = select_fd_set_bits_alloc(); + if (!tmp->cb[i].nstack_readset.fds_bits || + !tmp->cb[i].nstack_writeset.fds_bits || + !tmp->cb[i].nstack_exceptset.fds_bits) + { + goto err_return; + } + } + + tmp->ready.nstack_readset.fds_bits = select_fd_set_bits_alloc(); + tmp->ready.nstack_writeset.fds_bits = select_fd_set_bits_alloc(); + tmp->ready.nstack_exceptset.fds_bits = select_fd_set_bits_alloc(); + if (!tmp->ready.nstack_readset.fds_bits || + !tmp->ready.nstack_writeset.fds_bits || + !tmp->ready.nstack_exceptset.fds_bits) { - return; + goto err_return; + } + + *entry = tmp; + return; + err_return: + nstack_select_entry_free(tmp); + *entry = NULL; +} + +void select_fail_stat(i32 nfds, + fd_set * readfd, fd_set * writefd, fd_set * exceptfd) +{ + i32 i; + i32 event_id = 0; + nstack_fd_Inf *fdInf = NULL; + + for (i = 0; i < nfds; i++) + { + + event_id = 0; + if (!((readfd && FD_ISSET(i, readfd)) || + (writefd && FD_ISSET(i, writefd)) || + (exceptfd && FD_ISSET(i, exceptfd)))) + { + continue; + } + + fdInf = nstack_get_valid_inf(i); + if ((NULL == fdInf) || !fdInf->ops + || (fdInf->rmidx != MOD_INDEX_FOR_STACKPOOL)) + { + continue; + } + if ((readfd) && (FD_ISSET(i, readfd))) + { + event_id |= EPOLLIN; + } + if ((writefd) && (FD_ISSET(i, writefd))) + { + event_id |= EPOLLOUT; + } + if ((exceptfd) && (FD_ISSET(i, exceptfd))) + { + event_id |= EPOLLERR; + } + nstack_dfx_state_update((u64) fdInf->rlfd, fdInf->rmidx, + DMM_APP_SELECT_FAIL, + (void *) ((u64_t) event_id)); } - select_set_index (fd, inx); } -i32 -select_module_init_child () +int nstack_select_processing(int nfds, fd_set * readfds, fd_set * writefds, + fd_set * exceptfds, struct timeval *timeout) { - pthread_t select_thread_id; - i32 retval; + int ret = -1; + struct select_module_info *select_module = get_select_module(); + struct select_entry *entry = NULL; - if (pthread_create (&select_thread_id, NULL, nstack_select_thread, NULL)) + nstack_select_entry_alloc(&entry); + if (NULL == entry) { - goto ERR_RET; + errno = ENOMEM; + NSSOC_LOGERR("select entry alloc fail"); + goto err_return; } + /* need init sem */ + select_sem_init(&entry->sem, 0, 0); /*do not need return value */ + + /* fix dead-code type */ + /*split select fd to each modules fd and save to entry */ + (void) select_cb_split_by_mod(nfds, readfds, writefds, exceptfds, entry); + + /*if all fd in default module we just calling it */ + if (entry->info.set_num <= 1) + { + + /*adapte linux */ + if ((select_module) + && (entry->info.index == select_module->default_mod)) + { + if (select_module->default_fun) + { + ret = + select_module->default_fun(nfds, readfds, writefds, + exceptfds, timeout); + } + else + { + ret = + nsfw_base_select(nfds, readfds, writefds, exceptfds, + timeout); + } + goto err_return; + } + } + + /*cheching if event ready or not */ + if (FALSE == select_scan(entry)) + { + NSSOC_LOGERR("select scan fail"); + goto err_return; + } + + if (entry->ready.readyset != 0) + { + goto scan_return; + } + + if (TIMEVAL_EQUAL_ZERO(timeout)) + { + goto scan_return; + } + + if (FALSE == select_add_cb(entry)) + { + errno = ENOMEM; + NSSOC_LOGERR("select entry add fail"); + goto err_return; + } + + if (NULL == timeout) + { + select_sem_wait(&entry->sem); /*do not need return value */ + } + else + { + long time_cost = 0; + long msec = 0; + if (nstack_timeval2msec(timeout, &msec)) + { + nstack_set_errno(EINVAL); + goto err_return; + } + ret = nstack_sem_timedwait(&entry->sem, msec, &time_cost); + if (ret < 0) + { + nstack_set_errno(EINVAL); + goto err_return; + } + + if (time_cost >= msec) + { + select_fail_stat(nfds, readfds, writefds, exceptfds); + timeout->tv_sec = 0; + timeout->tv_usec = 0; + } + else if (time_cost > 0) + { + msec = msec - time_cost; + timeout->tv_sec = msec / 1000; + timeout->tv_usec = (msec % 1000) * 1000; + } + } + + select_rm_cb(entry); /*do not need return value */ + + scan_return: + ret = select_scan_return_from_entry(readfds, writefds, exceptfds, entry); - retval = pthread_setname_np (select_thread_id, "nstack_select_child"); - if (retval) + err_return: + if (entry) { - /*set thread name failed */ + nstack_select_entry_free(entry); } - return TRUE; + NSSOC_LOGDBG + ("nfds=%d,readfds=%p,writefds=%p,exceptfds=%p,timeout=%p,ret=%d errno=%d", + nfds, readfds, writefds, exceptfds, timeout, ret, errno); -ERR_RET: - return FALSE; + return ret; } #endif /* NSTACK_SELECT_MODULE */ |