第二人生的源码分析(四十三)虚拟文件系统线程

由于第二人生是一个3D显示的软件,因此它就需要不断地从服务器下载大量数据,比如纹理图片,不同的角色是使用不同的纹理图片来实现不同的衣服外表的。当显示这些角色时,就使用从服务器下载的纹理图片。如果显示的人物角色比较多,比如有30个人时,这些纹理图片就需要保存到磁盘里。那么怎么样保存到磁盘里呢?保存到磁盘里就需要一个好的文件系统来保存,以及读取数据出来。读写磁盘是一项比较慢的工作,因此需要使用一个线程来实现。还有时读写文件并不需要及时性的动作,可以让线程等到CPU空闲时再去做这些事情。
 
LLVFSThread类是继承LLQueuedThread类,这样LLVFSThread就变成消息循环处理类了。只需要不断地添加请求到消息队列里,然后再实现消息处理函数,就实现相应的功能了。
#001 //static
#002 void LLVFSThread::initClass(bool local_is_threaded)
#003 {
#004       llassert(sLocal == NULL);
#005       sLocal = new LLVFSThread(local_is_threaded);
#006 }
上面实始化虚拟文件系统线程类。
 
 
#001 LLVFSThread::handle_t LLVFSThread::read(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
#002                                                                      U8* buffer, S32
#003 offset, S32 numbytes, U32 priority, U32 flags)
#004 {
 
获取处理的句柄。
#005       handle_t handle = generateHandle();
#006 
 
获取这个请求的执行优先级。
#007       priority = llmax(priority, (U32)PRIORITY_LOW); // All reads are at least PRIORITY_LOW
 
创建读取数据请求消息。
#008       Request* req = new Request(handle, priority, flags, FILE_READ, vfs, file_id, file_type,
#009                                                    buffer, offset, numbytes);
#010 
 
添加这个消息到消息队列。
#011       bool res = addRequest(req);
#012       if (!res)
#013       {
#014              llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
#015              req->deleteRequest();
#016              handle = nullHandle();
#017       }
#018 
#019       return handle;
#020 }
 
虚拟文件系统需要实现读取里面的文件数据出来,上面函数LLVFSThread::read就是实现这样的功能。
 
#001 S32 LLVFSThread::readImmediate(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
#002                                                    U8* buffer, S32 offset, S32 numbytes)
#003 {
 
获取线程句柄。
#004       handle_t handle = generateHandle();
#005 
 
创建立即读取数据请求,主要优先级不一样。
#006       Request* req = new Request(handle, PRIORITY_IMMEDIATE, 0, FILE_READ, vfs, file_id, file_type,
#007                                                    buffer, offset, numbytes);
#008      
 
添加请求到消息队列。
#009       S32 res = addRequest(req) ? 1 : 0;
#010       if (res == 0)
#011       {
#012              llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
#013              req->deleteRequest();
#014       }
#015       else
#016       {
#017              llverify(waitForResult(handle, false) == true);
#018              res = req->getBytesRead();
#019              completeRequest(handle);
#020       }
#021       return res;
#022 }
 
上面的函数实现立即读取数据的要求。
 
#001 LLVFSThread::handle_t LLVFSThread::write(LLVFS* vfs, const LLUUID &file_id, const LLAssetType::EType file_type,
#002                                                                       U8* buffer, S32
#003 offset, S32 numbytes, U32 flags)
#004 {
 
获取线程句柄。
#005       handle_t handle = generateHandle();
#006 
 
添加写文件数据到虚拟文件系统的请求。
#007       Request* req = new Request(handle, 0, flags, FILE_WRITE, vfs, file_id, file_type,
#008                                                    buffer, offset, numbytes);
#009 
 
添加消息请求到消息队列。
#010       bool res = addRequest(req);
#011       if (!res)
#012       {
#013              llerrs << "LLVFSThread::read called after LLVFSThread::cleanupClass()" << llendl;
#014              req->deleteRequest();
#015              handle = nullHandle();
#016       }
#017      
#018       return handle;
#019 }
 
上面的函数实现写数据到虚拟文件系统的消息请求。在其后面还有LLVFSThread::writeImmediate函数,这个函数实现立即写数据到虚拟文件系统的请求。通过四个函数就可以添加读取数据和写数据到虚拟文件系统的请求,而这些请求又是怎么样处理的呢?下次再带你去理解它。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值