xi_pollset_t *xi_pollset_create(xuint32 size, xint32 opt) { xint32 rv; xi_pollset_t *pset = xi_mem_calloc(1, sizeof(xi_pollset_t)); if (pset == NULL) { return NULL; } pset->pfds = xi_mem_calloc(size, sizeof(xi_pollfd_t)); if (pset->pfds == NULL) { xi_mem_free(pset); return NULL; } pset->size = size; pset->used = 0; pset->opt = opt; if (pset->opt & XI_POLLSET_OPT_USELOCK) { rv = xi_thread_mutex_create(&pset->lock, "xg_poll"); if (rv < 0) { xi_mem_free(pset->pfds); xi_mem_free(pset); return NULL; } } FD_ZERO(&pset->set_read); FD_ZERO(&pset->set_write); FD_ZERO(&pset->set_except); return pset; }
static xvoid tc_client_recv(xi_pollset_t *pset, xi_pollfd_t *pfd) { xssize ret; xi_pollfd_t cpfd; struct ecb *ecbp = (struct ecb *)pfd->context; log_print(XDLOG, "Client receive\n"); ecbp->buflen = xi_socket_recv(pfd->desc, ecbp->buf, sizeof(ecbp->buf)); log_print(XDLOG, "received: %d bytes\n", ecbp->buflen); if (ecbp->buflen < 0) { log_error(XDLOG, "Failed to receive from the socket: %d\n", ecbp->buflen); --_g_client_num; _g_run = FALSE; xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } else if (ecbp->buflen == 0) { log_print(XDLOG, "EOF! Disconnected. Close the client socket\n"); --_g_client_num; ret = xi_pollset_remove(pset, *pfd); if (ret != XI_POLLSET_RV_OK) { log_error(XDLOG, "Failed to remove the read filter: %d\n", ret); _g_run = FALSE; xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } if (_g_client_num == 0) { log_print(XDLOG, "All clients have been disconnected. Exit this echo server.\n\n"); _g_run = FALSE; } xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } // setup a write event cpfd.desc = pfd->desc; cpfd.evts = XI_POLL_EVENT_OUT; cpfd.context = ecbp; // disable read ret = xi_pollset_remove(pset, *pfd); if (ret != XI_POLLSET_RV_OK) { log_error(XDLOG, "Failed to remove the read filter: %d\n", ret); _g_run = FALSE; xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } // enable write ret = xi_pollset_add(pset, cpfd); if (ret != XI_POLLSET_RV_OK) { log_error(XDLOG, "Failed to add a write filter: %d\n", ret); _g_run = FALSE; xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } }
xi_dir_t *xi_dir_open(const xchar *pathname) { WIN32_FIND_DATA ddat; xi_dir_t *dfd; xchar buf[XCFG_PATHNAME_MAX]; if (pathname == NULL) { return NULL; } dfd = xi_mem_alloc(sizeof(xi_dir_t)); if (dfd == NULL) { return NULL; } xi_strcpy(buf, pathname); xi_strcat(buf, "/*"); dfd->dfd = FindFirstFile(buf, &ddat); if (dfd->dfd == NULL) { xi_mem_free(dfd); return NULL; } xi_strcpy(dfd->pathname, pathname); return dfd; }
static xvoid tc_client_send(xi_pollset_t *pset, xi_pollfd_t *pfd) { xssize ret; xi_pollfd_t cpfd; struct ecb *ecbp = (struct ecb *)pfd->context; log_print(XDLOG, "Client send\n"); ret = xi_socket_send(pfd->desc, ecbp->buf, (xsize)ecbp->buflen); if (ret < 0) { log_error(XDLOG, "Failed to send to the socket: %d\n", ret); --_g_client_num; _g_run = FALSE; xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } log_print(XDLOG, "sent: %d bytes\n", ret); // setup a read event cpfd.desc = pfd->desc; cpfd.evts = XI_POLL_EVENT_IN; cpfd.context = ecbp; // disable write ret = xi_pollset_remove(pset, *pfd); if (ret != XI_POLLSET_RV_OK) { log_error(XDLOG, "Failed to remove the write filter: %d\n", ret); --_g_client_num; _g_run = FALSE; xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } // enable read ret = xi_pollset_add(pset, cpfd); if (ret != XI_POLLSET_RV_OK) { log_error(XDLOG, "Failed to add a read filter: %d\n", ret); --_g_client_num; _g_run = FALSE; xi_socket_close(pfd->desc); xi_mem_free(ecbp); return; } }
xi_pollset_re xi_pollset_destroy(xi_pollset_t *pset) { if (pset == NULL) { return XI_POLLSET_RV_ERR_ARGS; } if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_lock(&pset->lock); } if (pset->opt & XI_POLLSET_OPT_USELOCK) { xi_thread_mutex_unlock(&pset->lock); } xi_thread_mutex_destroy(&pset->lock); xi_mem_free(pset->pfds); xi_mem_free(pset); return XI_POLLSET_RV_OK; }
static xvoid tc_accept_client(xi_pollset_t *pset, xi_pollfd_t *pfd) { int ret; xi_sock_t clisock; xi_sock_addr_t cliaddr; struct ecb *ecb_client; xi_pollfd_t cpfd; // accept a client log_print(XDLOG, "Accept a client\n"); clisock = xi_socket_accept(pfd->desc, &cliaddr); if (clisock < 0) { log_error(XDLOG, "Failed to accept a client!!\n"); _g_run = FALSE; return; } // set an event control block for the new client ecb_client = (struct ecb *) xi_mem_calloc(1, sizeof(struct ecb)); ecb_client->do_read = &tc_client_recv; ecb_client->do_write = &tc_client_send; // setup an event for the client cpfd.desc = clisock; cpfd.evts = XI_POLL_EVENT_IN; cpfd.context = ecb_client; // add the client to the pollset log_print(XDLOG, "register client> clisock: %d, ctx: %p\n", clisock, cpfd.context); ret = xi_pollset_add(pset, cpfd); if (ret != XI_POLLSET_RV_OK) { log_error(XDLOG, "Failed to register a client: %d\n", ret); _g_run = FALSE; xi_mem_free(ecb_client); xi_socket_close(clisock); return; } ++_g_client_num; }
xvoid xi_sel_fddestroy(xi_fdset_t *fdset) { if (fdset == NULL) { return; } xi_mem_free(fdset); }