void list_swap(struct list_head *pa, struct list_head *pb) { struct list_head tmp; __list_add(&tmp, pa, pa->next); node_del(pa); __list_add(pa, pb, pb->next); node_del(pb); __list_add(pb, &tmp, tmp.next); node_del(&tmp); }
static void node_del(struct bcrb_node *node, bcrb_freefunc keyfree, bcrb_freefunc valfree) { if (!node) return; node_del(node->left, keyfree, valfree); node_del(node->right, keyfree, valfree); if (keyfree) keyfree(node->key); if (valfree) valfree(node->val); free(node); }
void bcrb_del(struct bcrb *tree, bcrb_freefunc keyfree, bcrb_freefunc valfree) { assert(tree); node_del(tree->root, keyfree, valfree); free(tree); }
static void purge(void) { avl_node_t *nnode, *nnext, *enode, *enext, *snode, *snext; node_t *n; edge_t *e; subnet_t *s; ifdebug(PROTOCOL) logger(LOG_DEBUG, "Purging unreachable nodes"); /* Remove all edges and subnets owned by unreachable nodes. */ for(nnode = node_tree->head; nnode; nnode = nnext) { nnext = nnode->next; n = nnode->data; if(!n->status.reachable) { ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Purging node %s (%s)", n->name, n->hostname); for(snode = n->subnet_tree->head; snode; snode = snext) { snext = snode->next; s = snode->data; send_del_subnet(everyone, s); if(!strictsubnets) subnet_del(n, s); } for(enode = n->edge_tree->head; enode; enode = enext) { enext = enode->next; e = enode->data; if(!tunnelserver) send_del_edge(everyone, e); edge_del(e); } } } /* Check if anyone else claims to have an edge to an unreachable node. If not, delete node. */ for(nnode = node_tree->head; nnode; nnode = nnext) { nnext = nnode->next; n = nnode->data; if(!n->status.reachable) { for(enode = edge_weight_tree->head; enode; enode = enext) { enext = enode->next; e = enode->data; if(e->to == n) break; } if(!enode && (!strictsubnets || !n->subnet_tree->head)) /* in strictsubnets mode do not delete nodes with subnets */ node_del(n); } } }
void list_insert_sort(struct list_head *phead, int (*cmp)(const struct list_head *a, const struct list_head *b)) { struct list_head *pi, *pj, *Next; for (pi = phead->next->next; pi != phead; pi = Next) { Next = pi->next; pj = pi->prev; if (cmp(pj, pi) <= 0) { continue; } node_del(pi); for (; pj != phead; pj = pj->prev) { if (cmp(pj, pi) < 0) { break; } } __list_add(pi, pj, pj->next); } }
int main(int argc, char *argv[]){ /* allocate node(s) in the heap */ node *head = malloc(sizeof(node)); head->val = 1; head->next = malloc(sizeof(node)); head->next->val = 2; head->next->next = NULL; list(head); push(head, 3); printf("----------\n"); list(head); node_del(&head, 2); printf("----------\n"); list(head); return 0; }
void _moddeinit(void) { node_t *n; xmlrpc_unregister_method("atheme.login"); xmlrpc_unregister_method("atheme.logout"); xmlrpc_unregister_method("atheme.command"); if ((n = node_find(&handle_xmlrpc, httpd_path_handlers)) != NULL) { node_del(n, httpd_path_handlers); node_free(n); } del_conf_item("PATH", &conf_xmlrpc_table); del_top_conf("XMLRPC"); free(xmlrpc_config.path); hook_del_config_ready(xmlrpc_config_ready); }
int main() { struct node* head = head_init(); int i; for(i=0; i<5; i++) { node_add(head, i); } printf_list(head); node_del(head, 3); printf_list(head); node_insert_after(head,2,6); printf_list(head); node_insert_before(&head,0,5); printf_list(head); node_insert_before(&head,6,8); printf_list(head); node_reverse(&head); printf_list(head); node_reverse_by_test(&head); printf_list(head); struct node* p = search_mid_node(head); printf("mid=%d\n", p->data); /* delete head emlement */ Remove_head(&head); printf_list(head); for(i=7; i<10; i++) { node_add(head, i); } printf_list(head); p = search_mid_node(head); printf("mid=%d\n", p->data); return 0; }
void destory() { int i; pthread_cancel(t_heartbeat); for (t_num; t_num > 0; t_num--) { pthread_cancel(tid[t_num]); } for (i = 0; i < MAX_ROOMS; i++) { pthread_mutex_destroy(&t_mutex_room[i]); } pthread_mutex_destroy(&t_mutex_hash); pthread_mutex_destroy(&t_mutex); pthread_cond_destroy(&t_cond); db_close(); hash_destroy(); if (fp) fclose(fp); for (i = 0; i < MAX_FDS; i++) { if (fd_clients[i] != NULL) { node_del(fd_clients[i]); } } }
int main() { t_min = 5; port = 5222; strncpy(dbhost, "localhost", MAX_CHAR_LENGTH); dbport = 3306; strncpy(dbuser, "root", MAX_CHAR_LENGTH); strncpy(dbpass, "123456", MAX_CHAR_LENGTH); strncpy(dbname, "ucenter", MAX_CHAR_LENGTH); strncpy(dbtable, "uc_members", MAX_CHAR_LENGTH); strncpy(fieldusername, "username", MAX_CHAR_LENGTH); strncpy(fieldpassword, "password", MAX_CHAR_LENGTH); int i; for (i = 0; i < MAX_FDS; i++) { fd_clients[i] = NULL; } for (i = 0; i < MAX_ROOMS; i++) { pthread_mutex_init(&t_mutex_room[i], NULL); rooms[i].enable = 0; rooms[i].num = 0; memset(rooms[i].name, '\0', sizeof (rooms[i].name)); rooms[i].client = NULL; } if (hash_create(MAX_USERS) == 0) { log_write(LOG_ERR, "hcreate error", __FILE__, __LINE__); return (EXIT_FAILURE); } rooms[0].enable = 1; strncpy(rooms[0].name, "Myleft聊天大厅", MAX_CHAR_LENGTH); lua_init(); lua_load_config(); lua_load_room(); db_connect(); //创建epoll句柄 epfd = epoll_create(MAX_FDS); int optval = 1; // 关闭之后重用socket unsigned int optlen = sizeof (optval); if ((s.listen_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { log_write(LOG_ERR, "socket error", __FILE__, __LINE__); destory(); return (EXIT_FAILURE); } log_write(LOG_DEBUG, "listen socked created", __FILE__, __LINE__); setsockopt(s.listen_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optlen)); //端口重用,如意外没有释放端口,还可以绑定成功 bzero(&s.listen_addr, sizeof (s.listen_addr)); //memset 适合大数据 s.listen_addr.sin_family = AF_INET; s.listen_addr.sin_port = htons(port); s.listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); //inet_addr("127.0.0.1"); if (bind(s.listen_sockfd, (struct sockaddr*) & s.listen_addr, sizeof (s.listen_addr)) < 0) { log_write(LOG_ERR, "bind error", __FILE__, __LINE__); destory(); return (EXIT_FAILURE); } if (listen(s.listen_sockfd, 3) < 0) { log_write(LOG_ERR, "listen error", __FILE__, __LINE__); destory(); return (EXIT_FAILURE); } printf("listenning......\n"); /* 设置socket为非阻塞模式,使用libevent编程这是必不可少的。 */ if (evutil_make_socket_nonblocking(s.listen_sockfd) < 0) { log_write(LOG_ERR, "evutil_make_socket_nonblocking error", __FILE__, __LINE__); destory(); return (EXIT_FAILURE); } //设置与要处理的事件相关的文件描述符 ev.data.fd = s.listen_sockfd; //设置要处理的事件类型 ev.events = EPOLLIN; int nfds; int client_fd; struct sockaddr_in client_addr; socklen_t client_len = sizeof (client_addr); char msgbuffer[MAX_BUFFER_LENGTH]; int recv_bits; //注册epoll事件 epoll_ctl(epfd, EPOLL_CTL_ADD, s.listen_sockfd, &ev); pthread_mutex_init(&t_mutex, NULL); pthread_cond_init(&t_cond, NULL); pthread_mutex_init(&t_mutex_hash, NULL); delay.tv_sec = 2; delay.tv_nsec = 0; //开启心跳线程heartbeat pthread_create(&t_heartbeat, NULL, heartbeat, NULL); //初始化任务线程,开启两个线程来完成任务,线程之间会互斥地访问任务链表 t_num = 0; while (t_num < t_min && t_num < T_MAX) { t_num++; pthread_create(&tid[t_num], NULL, readtask, NULL); } clients *client_fdnode; int logout = 0; while (1) { //等待epoll事件的发生 nfds = epoll_wait(epfd, events, MAX_EVENTS, 3000); //处理所发生的所有事件 for (i = 0; i < nfds; ++i) { time(&mytimestamp); p = gmtime(&mytimestamp); printf("fd:%d, file:%s, line:%d\n", events[i].data.fd, __FILE__, __LINE__); if (events[i].data.fd == s.listen_sockfd) {//主socket client_fd = accept(s.listen_sockfd, (struct sockaddr *) & client_addr, &client_len); if (client_fd < 0) { perror("connfd<0"); } evutil_make_socket_nonblocking(client_fd); clients *node = (clients *) malloc(sizeof (clients)); node->fd = client_fd; node->roomid = -1; node->state = FD_STATE_WAIT; node->type = CLIENT_TYPE_NONE; node->anonymous = 1; node->x = 1; node->y = 1; node->keepalivetime = mytimestamp; //node->username[0] = '\0'; memset(node->username, 1 ,sizeof(node->username));//bzero(c, sizeof(c)); node->next = NULL; fd_clients[client_fd] = node; ev.events = EPOLLIN | EPOLLET; ev.data.fd = client_fd; epoll_ctl(epfd, EPOLL_CTL_ADD, client_fd, &ev); log_write(LOG_DEBUG, "epoll_ctl", __FILE__, __LINE__); } else if (events[i].events & EPOLLIN) { logout = 0; memset(msgbuffer, '\0', sizeof (msgbuffer)); printf("msgbuffer:%s", msgbuffer); if (events[i].data.fd < 0) { continue; } client_fdnode = fd_clients[events[i].data.fd]; if (client_fdnode == NULL) { events[i].data.fd = -1; close(events[i].data.fd); } client_fdnode->keepalivetime = mytimestamp; recv_bits = read(events[i].data.fd, msgbuffer, sizeof (msgbuffer)); if (recv_bits <= 0) { printf("recv_bits:%d, file:%s, line:%d\n", recv_bits, __FILE__, __LINE__); logout = 1; events[i].data.fd = -1; if (client_fdnode->state != FD_STATE_SUCCESS) { node_del(client_fdnode); continue; //退出 } } else if (recv_bits >= MAX_BUFFER_LENGTH) { log_write(LOG_DEBUG, "recv_bits>", __FILE__, __LINE__); logout = 1; events[i].data.fd = -1; if (client_fdnode->state != FD_STATE_SUCCESS) { node_del(client_fdnode); continue; //退出 } } else if (strncmp(msgbuffer, PING, sizeof (PING)) == 0) { send_message(client_fdnode->fd, "<event type='0'/>"); continue; //退出 } else if (strncmp(msgbuffer, QUIT, sizeof (QUIT)) == 0) { log_write(LOG_DEBUG, "QUIT", __FILE__, __LINE__); logout = 1; events[i].data.fd = -1; if (client_fdnode->state != FD_STATE_SUCCESS) { node_del(client_fdnode); continue; //退出 } } else if (strncmp(msgbuffer, POLICY, sizeof (POLICY)) == 0) { printf("msg:%s, file:%s, line:%i\n", crossdomain, __FILE__, __LINE__); //send_message(events[i].data.fd, crossdomain); write(events[i].data.fd, crossdomain, MAX_BUFFER_LENGTH); continue; //退出 } log_write(LOG_DEBUG, "添加新的读任务", __FILE__, __LINE__); //添加新的读任务 struct task *new_task = (struct task *) malloc(sizeof (struct task)); if (new_task != NULL) { new_task->client = client_fdnode; new_task->logout = logout; new_task->data = (char *) malloc(MAX_BUFFER_LENGTH * sizeof (char)); strcpy(new_task->data, msgbuffer); new_task->next = NULL; log_write(LOG_DEBUG, "new_task", __FILE__, __LINE__); pthread_mutex_lock(&t_mutex); if (task_head == NULL) { task_head = new_task; } else { struct task *temp_task; temp_task = task_head; while (temp_task->next != NULL) { temp_task = temp_task->next; } temp_task->next = new_task; } //唤醒其中一个线程即可 log_write(LOG_DEBUG, "唤醒所有等待cond1条件的线程", __FILE__, __LINE__); pthread_cond_signal(&t_cond); //唤醒所有等待cond1条件的线程 //log_write(LOG_DEBUG, "唤醒所有等待cond1条件的线程", __FILE__, __LINE__); //pthread_cond_broadcast(&t_cond); pthread_mutex_unlock(&t_mutex); } } else if (events[i].events & EPOLLOUT) { if (events[i].data.fd < 0) { continue; } //设置用于读操作的文件描述符 ev.data.fd = events[i].data.fd; //设置用于注测的读操作事件 ev.events = EPOLLIN | EPOLLET; //修改sockfd上要处理的事件为EPOLIN epoll_ctl(epfd, EPOLL_CTL_MOD, events[i].data.fd, &ev); } else if (events[i].events & EPOLLRDHUP) {//tcp连接中断检测 if (events[i].data.fd < 0) { continue; } client_fdnode = fd_clients[events[i].data.fd]; if (client_fdnode == NULL) { events[i].data.fd = -1; close(events[i].data.fd); } log_write(LOG_DEBUG, "EPOLLRDHUP 对方断开", __FILE__, __LINE__); events[i].data.fd = -1; node_del(client_fdnode); continue; } else if (events[i].events & EPOLLERR) {//tcp连接中断检测 if (events[i].data.fd < 0) { continue; } client_fdnode = fd_clients[events[i].data.fd]; if (client_fdnode == NULL) { events[i].data.fd = -1; close(events[i].data.fd); } log_write(LOG_DEBUG, "EPOLLERR 对方断开", __FILE__, __LINE__); events[i].data.fd = -1; node_del(client_fdnode); continue; } else { perror("other event"); } printf("一次小循环\n"); } } close(s.listen_sockfd); destory(); return (EXIT_SUCCESS); }