/* * gmph_destroy_client * * Destroy a client entry. Destroys any client groups still bound to the * client, though the groups themselves live on (possibly attempting to * send Leaves if no other clients are interested in the groups.) */ void gmph_destroy_client (gmph_client *client) { gmph_instance *instance; gmpx_patnode *node; gmph_client_group *client_group; instance = client->hclient_instance; /* Flush the tree. */ while (TRUE) { node = gmpx_patricia_lookup_least(client->hclient_group_root); client_group = gmph_patnode_to_client_group(node); if (!client_group) break; gmph_destroy_client_group(client_group, TRUE); } /* Get rid of the tree. */ gmpx_assert(!gmpx_patricia_lookup_least(client->hclient_group_root)); gmpx_patroot_destroy(client->hclient_group_root); client->hclient_group_root = NULL; /* Delink the block and free it. */ thread_remove(&client->hclient_thread); client->hclient_instance = NULL; gmpx_free_block(gmph_client_tag, client); }
/* * gmph_destroy_client_group * * Destroy a client group entry. Tolerant of unlinked entries, to make it * easier to back out during memory shortages. * * reevaluate_group is TRUE if we should reevaluate our group state. */ void gmph_destroy_client_group (gmph_client_group *client_group, boolean reevaluate_group) { gmph_client *client; gmph_group *group; /* Delink it. */ group = client_group->client_group_group; client = client_group->client_group_client; gmpx_patricia_delete(client->hclient_group_root, &client_group->client_group_node); thread_remove(&client_group->client_group_thread); /* Clean it out. */ gmp_addr_vect_clean(&client_group->client_addr_vect); /* Free the block. */ gmpx_free_block(gmph_client_group_tag, client_group); /* Reevaluate the group if appropriate. */ if (reevaluate_group) gmph_reevaluate_group(group); /* Try to free the group. */ gmph_attempt_group_free(group); }
void MonitorNetlinkUevent() { pthread_t tid1; pthread_mutex_init(&m_lock, NULL); pthread_cond_init(&poweroff_ready, NULL); pthread_create(&tid1, NULL, power_thread, NULL); //sleep(1); initial_check_usb(); int sockfd; struct sockaddr_nl sa; int len; char buf[4096]; struct iovec iov; struct msghdr msg; int i; char ins[]="add"; char out[]="remove"; int res; int off; memset(&sa,0,sizeof(sa)); sa.nl_family=AF_NETLINK; sa.nl_groups=NETLINK_KOBJECT_UEVENT; sa.nl_pid = 0;//getpid(); both is ok //①、创建一个socket描述符 sockfd=socket(AF_NETLINK,SOCK_RAW,NETLINK_KOBJECT_UEVENT); if(sockfd==-1) printf("socket creating failed:%s\n",strerror(errno)); //②、将描述符绑定到接收地址, 函数 bind() 用于把一个打开的 netlink socket 和 netlink 源 socket 地址绑定在一起 if(bind(sockfd,(struct sockaddr *)&sa,sizeof(sa))==-1) printf("bind error:%s\n",strerror(errno)); while(1) { //printf("monitor round\r\n"); memset(&msg,0,sizeof(msg)); iov.iov_base=(void *)buf; iov.iov_len=sizeof(buf); msg.msg_name=(void *)&sa; msg.msg_namelen=sizeof(sa); msg.msg_iov=&iov; msg.msg_iovlen=1; //③开始接收uevent len=recvmsg(sockfd,&msg,0); if(len<0) printf("receive error\n"); else if(len<32||len>sizeof(buf)) printf("invalid message"); if(passnumber) { printf("continue !!!!\n"); continue; } passnumber=1; for(i=0; i<len; i++) if(*(buf+i)=='\0') buf[i]='\n'; //printf("%s\n", buf); res=strncasecmp(ins,buf,strlen(ins)); off=strncasecmp(out,buf,strlen(out)); if(!res) { printf("device insert\n"); thread_insert(); } if(!off) { printf("device remove\n"); thread_remove(); } } }