/*
 * 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);
}
Exemple #3
0
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();
        }


    }

}