DirectFB源代码阅读(五)dfb_system_lookup .

dfb_system_lookup的作用就是找到当前系统运行程序的环境,比如x11,fbdev,devmem,dummy.

  1. dfb_system_lookup( void )  
  2. {  
  3.      direct_modules_explore_directory( &dfb_core_systems );//得到所有的可以使用的system,这里是遍历系统system目录,把动态库加入到链表中   
  4.      direct_list_foreach( l, dfb_core_systems.entries ) {  
  5.           funcs = direct_module_ref( module );//增加一个使用引用   
  6.   
  7.           if (!system_module || (!dfb_config->system ||  
  8.               !strcasecmp( dfb_config->system, module->name )))//判断当前的模块与系统要使用的模块名字是否相同   
  9.           {  
  10.                if (system_module)//标识不再使用现在的系统模块   
  11.                     direct_module_unref( system_module );  
  12.   
  13.                system_module = module;//更新系统使用的system模块   
  14.                system_funcs  = funcs;  
  15.   
  16.                funcs->GetSystemInfo( &system_info );//获取系统模块的信息   
  17.           }  
  18.      }  
  19.      return DFB_OK;  
  20. }  
dfb_system_lookup( void )
{
     direct_modules_explore_directory( &dfb_core_systems );//得到所有的可以使用的system,这里是遍历系统system目录,把动态库加入到链表中
     direct_list_foreach( l, dfb_core_systems.entries ) {
          funcs = direct_module_ref( module );//增加一个使用引用

          if (!system_module || (!dfb_config->system ||
              !strcasecmp( dfb_config->system, module->name )))//判断当前的模块与系统要使用的模块名字是否相同
          {
               if (system_module)//标识不再使用现在的系统模块
                    direct_module_unref( system_module );

               system_module = module;//更新系统使用的system模块
               system_funcs  = funcs;

               funcs->GetSystemInfo( &system_info );//获取系统模块的信息
          }
     }
     return DFB_OK;
}
1.dfb_core_systems

在core/system.c里面定义的一个全局的DirectModuleDir变量.使用双向链表把所有的system存放在里面.

  1. struct __D_DirectModuleDir {  
  2.      pthread_mutex_t    lock;  
  3.   
  4.      const char        *path;//路径   
  5.      unsigned int       abi_version;  
  6.   
  7.      DirectLink        *entries;//双向链表   
  8.   
  9.      DirectModuleEntry *loading;//模块信息   
  10. };  
struct __D_DirectModuleDir {
     pthread_mutex_t    lock;

     const char        *path;//路径
     unsigned int       abi_version;

     DirectLink        *entries;//双向链表

     DirectModuleEntry *loading;//模块信息
};
2. direct_modules_explore_directory

  1. int direct_modules_explore_directory( DirectModuleDir *directory )  
  2. {  
  3.      dir = opendir( buf );  
  4.   
  5.      while (readdir_r( dir, &tmp, &entry ) == 0 && entry) {  
  6.           void              *handle;  
  7.           DirectModuleEntry *module;  
  8.           int                entry_len = strlen(entry->d_name);  
  9.   
  10.           if (entry_len < 4 ||                //库文件以.so结尾   
  11.               entry->d_name[entry_len-1] != 'o' ||  
  12.               entry->d_name[entry_len-2] != 's')  
  13.                continue;  
  14.   
  15.           if (lookup_by_file( directory, entry->d_name ))//如果在链表中已经有这个库了,不需要再做下面的操作   
  16.                continue;  
  17.   
  18.           module = D_CALLOC( 1, sizeof(DirectModuleEntry) );  
  19.   
  20.           D_MAGIC_SET( module, DirectModuleEntry );  
  21.   
  22.           module->directory = directory;  
  23.           module->dynamic   = true;  
  24.           module->file      = D_STRDUP( entry->d_name );  
  25.   
  26.           directory->loading = module;  
  27.   
  28.           if ((handle = open_module( module )) != NULL) {//调用dlopen,进行自动化注册   
  29.                if (!module->loaded) {//自动化注册没有成功进行手动注册    
  30.                     int    len;  
  31.                     void (*func)( void );  
  32.   
  33.                     len = strlen( entry->d_name );  
  34.   
  35.                     entry->d_name[len-3] = 0;//去掉库名字里面的.so   
  36.            //去掉库名字里面的lib,如果是libdirectfb_fbdev.so,就成了directfb_fbdev,在哪定义的呢   
  37.                     func = dlsym( handle, entry->d_name + 3 );   
  38.                     if (func) {   
  39.                         func();   
  40.                     }   
  41.                     if (!module->loaded) {//标识模块不可使用,并把它加入到链表里面以节约时间    
  42.                         module->disabled = true;   
  43.                         direct_list_prepend( &directory->entries, &module->link );   
  44.                     }   
  45.               }   
  46.               if (module->disabled) {//如果库不可以使用就把它关掉 module->loaded = false; /* may call direct_modules_unregister() */    
  47.                    dlclose( handle );   
  48.               }   
  49.               else {   
  50.                    module->handle = handle; count++;   
  51.               }   
  52.          }   
  53.          else { //无法打开也把这个库加入到链表里为以后搜索节约时间    
  54.              module->disabled = true;   
  55.              direct_list_prepend( &directory->entries, &module->link );   
  56.          }   
  57.          directory->loading = NULL;   
  58.      }   
  59.      closedir( dir );   
  60.      return count;  
  61. }  
int direct_modules_explore_directory( DirectModuleDir *directory )
{
     dir = opendir( buf );

     while (readdir_r( dir, &tmp, &entry ) == 0 && entry) {
          void              *handle;
          DirectModuleEntry *module;
          int                entry_len = strlen(entry->d_name);

          if (entry_len < 4 ||                //库文件以.so结尾
              entry->d_name[entry_len-1] != 'o' ||
              entry->d_name[entry_len-2] != 's')
               continue;

          if (lookup_by_file( directory, entry->d_name ))//如果在链表中已经有这个库了,不需要再做下面的操作
               continue;

          module = D_CALLOC( 1, sizeof(DirectModuleEntry) );

          D_MAGIC_SET( module, DirectModuleEntry );

          module->directory = directory;
          module->dynamic   = true;
          module->file      = D_STRDUP( entry->d_name );

          directory->loading = module;

          if ((handle = open_module( module )) != NULL) {//调用dlopen,进行自动化注册
               if (!module->loaded) {//自动化注册没有成功进行手动注册 
                    int    len;
                    void (*func)( void );

                    len = strlen( entry->d_name );

                    entry->d_name[len-3] = 0;//去掉库名字里面的.so
           //去掉库名字里面的lib,如果是libdirectfb_fbdev.so,就成了directfb_fbdev,在哪定义的呢
                    func = dlsym( handle, entry->d_name + 3 ); 
                    if (func) { 
                        func(); 
                    } 
                    if (!module->loaded) {//标识模块不可使用,并把它加入到链表里面以节约时间 
                        module->disabled = true; 
                        direct_list_prepend( &directory->entries, &module->link ); 
                    } 
              } 
              if (module->disabled) {//如果库不可以使用就把它关掉 module->loaded = false; /* may call direct_modules_unregister() */ 
                   dlclose( handle ); 
              } 
              else { 
                   module->handle = handle; count++; 
              } 
         } 
         else { //无法打开也把这个库加入到链表里为以后搜索节约时间 
             module->disabled = true; 
             direct_list_prepend( &directory->entries, &module->link ); 
         } 
         directory->loading = NULL; 
     } 
     closedir( dir ); 
     return count;
}

这里还有两个问题没有搞明白:dlopen,dlsym.

在dlopen的man手册里面有这么一句话:

Instead, libraries should export routines using the __attribute__((constructor)) and __attribute__((destructor)) function attributes. See the gcc info pages for information on these. Constructor routines are executed before dlopen() returns, and destructor routines are executed before dlclose() returns.

也就是在调用dlopen打开这个库的时候,被标识的构造函数将被先执行.

在core_system.h,可以看到direct_modules_register被标识库constructor,将先被执行.很是自动化.

  1. void direct_modules_register( DirectModuleDir *directory,  
  2.                          unsigned int     abi_version,  
  3.                          const char      *name,  
  4.                          const void      *funcs )  
  5. {  
  6.      if (directory->loading) {  
  7.           entry = directory->loading;//取得临时存放的模块   
  8.           D_MAGIC_ASSERT( entry, DirectModuleEntry );  
  9.   
  10.           directory->loading = NULL;  
  11.      }  
  12.   
  13.      entry->directory = directory;  
  14.      entry->loaded    = true;//标识载入成功   
  15.      entry->name      = D_STRDUP( name );  
  16.      entry->funcs     = funcs;  
  17.   
  18.      entry->disabled  = suppress_module( name );  
  19.   
  20.      if (abi_version != directory->abi_version) {  
  21.          entry->disabled = true;  
  22.      }  
  23.      direct_list_prepend( &directory->entries, &entry->link );//加入到链表里面   
  24. }  
void direct_modules_register( DirectModuleDir *directory,
                         unsigned int     abi_version,
                         const char      *name,
                         const void      *funcs )
{
     if (directory->loading) {
          entry = directory->loading;//取得临时存放的模块
          D_MAGIC_ASSERT( entry, DirectModuleEntry );

          directory->loading = NULL;
     }

     entry->directory = directory;
     entry->loaded    = true;//标识载入成功
     entry->name      = D_STRDUP( name );
     entry->funcs     = funcs;

     entry->disabled  = suppress_module( name );

     if (abi_version != directory->abi_version) {
         entry->disabled = true;
     }
     direct_list_prepend( &directory->entries, &entry->link );//加入到链表里面
}
如果上面没有自动执行,也就是我们并没有对这个函数进行construct标识,那么就可以调用dlsym找到这个函数,进行手动执行了.

dlsym第一个参数是模块的处理句柄,第二个参数是函数的名称,而这个函数directfb_fbdev又是在哪定义的呢?

在fbdev.c里面调用了宏DFB_CORE_SYSTEM( fbdev ),这样就找到了directfb_fbdev的定义

  1. #define DFB_CORE_SYSTEM(shortname)                              \   
  2. __attribute__((constructor)) void directfb_##shortname( void ); \  
  3.                                                                 \  
  4. void                                                            \  
  5. directfb_##shortname( void )                                    \  
  6. {                                                               \  
  7.      direct_modules_register( &dfb_core_systems,                \  
  8.                               DFB_CORE_SYSTEM_ABI_VERSION,      \  
  9.                               #shortname, &system_funcs );      \   
  10. }  
#define DFB_CORE_SYSTEM(shortname)                              \
__attribute__((constructor)) void directfb_##shortname( void ); \
                                                                \
void                                                            \
directfb_##shortname( void )                                    \
{                                                               \
     direct_modules_register( &dfb_core_systems,                \
                              DFB_CORE_SYSTEM_ABI_VERSION,      \
                              #shortname, &system_funcs );      \
}

通过查看devmem,dummy,fbdev,osx,sdl,vnc,x11这些system的具体实现,可以看到它们都是实现也下面的结构体中的函数,然后通过这个结构体注册到系统中.

  1. static CoreSystemFuncs system_funcs = {  
  2.      .GetSystemInfo       = system_get_info,  
  3.      .Initialize          = system_initialize,  
  4.      .Join                = system_join,  
  5.      .Shutdown            = system_shutdown,  
  6.      .Leave               = system_leave,  
  7.      .Suspend             = system_suspend,  
  8.      .Resume              = system_resume,  
  9.      .GetModes            = system_get_modes,  
  10.      .GetCurrentMode      = system_get_current_mode,  
  11.      .ThreadInit          = system_thread_init,  
  12.      .InputFilter         = system_input_filter,  
  13.      .MapMMIO             = system_map_mmio,  
  14.      .UnmapMMIO           = system_unmap_mmio,  
  15.      .GetAccelerator      = system_get_accelerator,  
  16.      .VideoMemoryPhysical = system_video_memory_physical,  
  17.      .VideoMemoryVirtual  = system_video_memory_virtual,  
  18.      .VideoRamLength      = system_videoram_length,  
  19.      .AuxMemoryPhysical   = system_aux_memory_physical,  
  20.      .AuxMemoryVirtual    = system_aux_memory_virtual,  
  21.      .AuxRamLength        = system_auxram_length,  
  22.      .GetBusID            = system_get_busid,  
  23.      .SurfaceDataSize     = system_surface_data_size,  
  24.      .SurfaceDataInit     = system_surface_data_init,  
  25.      .SurfaceDataDestroy  = system_surface_data_destroy,  
  26.      .GetDeviceID         = system_get_deviceid  
  27. };  
static CoreSystemFuncs system_funcs = {
     .GetSystemInfo       = system_get_info,
     .Initialize          = system_initialize,
     .Join                = system_join,
     .Shutdown            = system_shutdown,
     .Leave               = system_leave,
     .Suspend             = system_suspend,
     .Resume              = system_resume,
     .GetModes            = system_get_modes,
     .GetCurrentMode      = system_get_current_mode,
     .ThreadInit          = system_thread_init,
     .InputFilter         = system_input_filter,
     .MapMMIO             = system_map_mmio,
     .UnmapMMIO           = system_unmap_mmio,
     .GetAccelerator      = system_get_accelerator,
     .VideoMemoryPhysical = system_video_memory_physical,
     .VideoMemoryVirtual  = system_video_memory_virtual,
     .VideoRamLength      = system_videoram_length,
     .AuxMemoryPhysical   = system_aux_memory_physical,
     .AuxMemoryVirtual    = system_aux_memory_virtual,
     .AuxRamLength        = system_auxram_length,
     .GetBusID            = system_get_busid,
     .SurfaceDataSize     = system_surface_data_size,
     .SurfaceDataInit     = system_surface_data_init,
     .SurfaceDataDestroy  = system_surface_data_destroy,
     .GetDeviceID         = system_get_deviceid
};
通过看每一个具体的system的实现,可以看到颜色,透明度等的设置,又可以学到相关的编程知识,进行进一步的知识扩展.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值