spice server qxl red_worker_main()代码分析

1.在qxl中red_dispatcher_init 非常重要

[cpp] view plain copy print ?
  1. RedDispatcher *red_dispatcher_init(QXLInstance *qxl)  
  2. {  
  3.     RedDispatcher *red_dispatcher;   // 创建RedDispatcher 结构指针  
  4.     RedWorkerMessage message;        // 定义一个消息,用来判断后面线程Red_worker发过来的ready消息  
  5.     WorkerInitData init_data;        // 定义一个WorkerInitData结构 用来存储创建Red_worker线程所需要的信息  
  6.     QXLDevInitInfo init_info;        // 定义qxl初始化数据  保存qxl worker 中函数 get_init_info获取的初始化qxl dev的信息  
  7.     int r;                           // 线程创建函数的返回参数  
  8.     RedChannel *display_channel;     // display_channel  
  9.     RedChannel *cursor_channel;      // cursor_channel  
  10.     sigset_t thread_sig_mask;        // thread_sig_mask 线程信号掩码   ??????  
  11.     sigset_t curr_sig_mask;          // curr_sig_mask 当前信号掩码     ??????  
  12.     ClientCbs client_cbs = { NULL, }; // client_cbs 回调函数     
  13.   
  14.   
  15.     quic_init();                     // quic 初始化  
  16.     sw_canvas_init();                //sw_canvas 初始化  
  17. #ifdef USE_OPENGL  
  18.     gl_canvas_init();                //gl初始化  
  19. #endif // USE_OPENGL  
  20.   
  21.   
  22.     red_dispatcher = spice_new0(RedDispatcher, 1);  // 为red_dispatcher分配内存  
  23.     ring_init(&red_dispatcher->async_commands);   //初始化red_dispatcher中的异步命令环  
  24.     spice_debug("red_dispatcher->async_commands.next %p", red_dispatcher->async_commands.next); //打印调试信息  
  25.     dispatcher_init(&red_dispatcher->dispatcher, RED_WORKER_MESSAGE_COUNT, NULL); // 初始化dispatcher创建套接字和给信息分配内存,后面详说  
  26.     init_data.qxl = red_dispatcher->qxl = qxl;  //把qxl指针传给前面两种结构,后面一次类推  主要是为后面创建red_worker线程做准备  
  27.     init_data.id = qxl->id;  
  28.     init_data.red_dispatcher = red_dispatcher;  
  29.     init_data.pending = &red_dispatcher->pending;  
  30.     init_data.num_renderers = num_renderers;  
  31.     memcpy(init_data.renderers, renderers, sizeof(init_data.renderers));  
  32.   
  33.     pthread_mutex_init(&red_dispatcher->async_lock, NULL);  
  34.     init_data.image_compression = image_compression;  
  35.     init_data.jpeg_state = jpeg_state;  
  36.     init_data.zlib_glz_state = zlib_glz_state;  
  37.     init_data.streaming_video = streaming_video; //上面的都是把一些有用的信息赋给init_data带给将要创建的线程red_worker,  
  38.   
  39.     red_dispatcher->base.major_version = SPICE_INTERFACE_QXL_MAJOR;  // 初始化red_dispatcher中的base成员qxl_worker  
  40.     red_dispatcher->base.minor_version = SPICE_INTERFACE_QXL_MINOR;  
  41.     red_dispatcher->base.wakeup = qxl_worker_wakeup;  
  42.     red_dispatcher->base.oom = qxl_worker_oom;  
  43.     red_dispatcher->base.start = qxl_worker_start;  
  44.     red_dispatcher->base.stop = qxl_worker_stop;  
  45.     red_dispatcher->base.update_area = qxl_worker_update_area;  
  46.     red_dispatcher->base.add_memslot = qxl_worker_add_memslot;  
  47.     red_dispatcher->base.del_memslot = qxl_worker_del_memslot;  
  48.     red_dispatcher->base.reset_memslots = qxl_worker_reset_memslots;  
  49.     red_dispatcher->base.destroy_surfaces = qxl_worker_destroy_surfaces;  
  50.     red_dispatcher->base.create_primary_surface = qxl_worker_create_primary_surface;  
  51.     red_dispatcher->base.destroy_primary_surface = qxl_worker_destroy_primary_surface;  
  52.   
  53.     red_dispatcher->base.reset_image_cache = qxl_worker_reset_image_cache;  
  54.     red_dispatcher->base.reset_cursor = qxl_worker_reset_cursor;  
  55.     red_dispatcher->base.destroy_surface_wait = qxl_worker_destroy_surface_wait;  
  56.     red_dispatcher->base.loadvm_commands = qxl_worker_loadvm_commands; //上面都是初始化qxl_worker 主要是版本信息和注册函数 这些函数具体会在什么地方调用呢,这个在另一片日志里面有记载,之后我也会更新到这篇日志中来的  
  57.   
  58.     qxl->st->qif->get_init_info(qxl, &init_info);  
  59.   
  60.     init_data.memslot_id_bits = init_info.memslot_id_bits; //有关worker中的memslot初始化信息  
  61.     init_data.memslot_gen_bits = init_info.memslot_gen_bits;  
  62.     init_data.num_memslots = init_info.num_memslots;  
  63.     init_data.num_memslots_groups = init_info.num_memslots_groups;  
  64.     init_data.internal_groupslot_id = init_info.internal_groupslot_id;  
  65.     init_data.n_surfaces = init_info.n_surfaces;  //上面都是有关worker中的memslot初始化信息  
  66.   
  67.     num_active_workers = 1;          //活动的worker有几个  
  68.   
  69.     sigfillset(&thread_sig_mask);     //信号集的设置 主要是设置某些 信号令red_worker线程对这些信号不发生反映??????  
  70.     sigdelset(&thread_sig_mask, SIGILL);  
  71.     sigdelset(&thread_sig_mask, SIGFPE);  
  72.     sigdelset(&thread_sig_mask, SIGSEGV);  
  73.     pthread_sigmask(SIG_SETMASK, &thread_sig_mask, &curr_sig_mask);  
  74.     if ((r = pthread_create(&red_dispatcher->worker_thread, NULL, red_worker_main, &init_data))) { //创建red_worker线程    
  75.         spice_error("create thread failed %d", r);  
  76.     }  
  77.     pthread_sigmask(SIG_SETMASK, &curr_sig_mask, NULL);   //设置信号集 ??????  
  78.   
  79.     read_message(red_dispatcher->dispatcher.send_fd, &message); //从套接字中阅读消息  
  80.     spice_assert(message == RED_WORKER_MESSAGE_READY);      //判断消息是否是RED_WORKER_MESSAGE_READY  
  81.   
  82.     display_channel = red_dispatcher_display_channel_create(red_dispatcher); // 创建display_channel通道  
  83.   
  84.     if (display_channel) {              //创建好了之后,注册client_cbs回调函数  
  85.         client_cbs.connect = red_dispatcher_set_display_peer;  
  86.         client_cbs.disconnect = red_dispatcher_disconnect_display_peer;  
  87.         client_cbs.migrate = red_dispatcher_display_migrate;  
  88.         red_channel_register_client_cbs(display_channel, &client_cbs);  
  89.         red_channel_set_data(display_channel, red_dispatcher);   //设置数据,令display_channel中的data指向red_dispatcher   
  90.         red_channel_set_cap(display_channel, SPICE_DISPLAY_CAP_MONITORS_CONFIG); //设置性能??????  
  91.         red_channel_set_cap(display_channel, SPICE_DISPLAY_CAP_STREAM_REPORT);  //设置性能??????  
  92.         reds_register_channel(display_channel);    //把channel挂到server的channel环上  
  93.     }  
  94.   
  95.     cursor_channel = red_dispatcher_cursor_channel_create(red_dispatcher); //与上面display_chennel类似  
  96.   
  97.     if (cursor_channel) {  
  98.         client_cbs.connect = red_dispatcher_set_cursor_peer;  
  99.         client_cbs.disconnect = red_dispatcher_disconnect_cursor_peer;  
  100.         client_cbs.migrate = red_dispatcher_cursor_migrate;  
  101.         red_channel_register_client_cbs(cursor_channel, &client_cbs);  
  102.         red_channel_set_data(cursor_channel, red_dispatcher);  
  103.         reds_register_channel(cursor_channel);  
  104.     }  
  105.   
  106.     qxl->st->qif->attache_worker(qxl, &red_dispatcher->base); //qxl_worker赋给qxl指针 ,,,,,,  
  107.     qxl->st->qif->set_compression_level(qxl, calc_compression_level());//设置压缩参数  
  108.   
  109.     red_dispatcher->next = dispatchers; //把创建的red_dispatcher挂到全局的dispatchers环中  
  110.     dispatchers = red_dispatcher;  
  111.     return red_dispatcher; //返回red_dispatcher  
  112. }  

 


2.上面red_dispatcher_init中的函数dispatcher没有详说,下面对其代码详细解析

[cpp] view plain copy print ?
  1. void dispatcher_init(Dispatcher *dispatcher, size_t max_message_type,  
  2.                      void *opaque)  
  3. {  
  4.     int channels[2]; //定义两个整形值,用来存储互相连接的两个套接字  
  5.   
  6. #ifdef DEBUG_DISPATCHER  
  7.     setup_dummy_signal_handler(); //虚拟信号处理 ??????  
  8. #endif  
  9.     dispatcher->opaque = opaque;  //赋值  
  10.     if (socketpair(AF_LOCAL, SOCK_STREAM, 0, channels) == -1) {  
  11.         spice_error("socketpair failed %s", strerror(errno));  
  12.         return;  
  13.     } //利用socketpair创建两个相互连接的套接字,用于主副线程之间的通信,主要用于message信息的传输  
  14.     pthread_mutex_init(&dispatcher->lock, NULL); //线程锁的初始化   
  15.     dispatcher->recv_fd = channels[0];  //将套接字赋给dispatcher成员  
  16.     dispatcher->send_fd = channels[1];  
  17.     dispatcher->self = pthread_self();  
  18.   
  19.     dispatcher->messages = spice_malloc0_n(max_message_type,  
  20.                                            sizeof(dispatcher->messages[0]));  //为message分配内存空间  
  21.     dispatcher->max_message_type = max_message_type;   // message最大类型赋值给dispatcher中的max_message_type  
  22. }  

 


 

你可能感兴趣的:(spice server qxl red_worker_main()代码分析)