zmq源码阅读——Msg.hpp & Msg.cpp 的 相关操作 (zmq中的消息)
来源:互联网 发布:优酷会员如何解绑淘宝 编辑:程序博客网 时间:2024/06/05 08:48
int zmq::msg_t::init_size (size_t size_){ if (size_ <= max_vsm_size) { u.vsm.type = type_vsm; // 小消息的类型为type_vsm,这个值为101,相当于一个魔法数字,用来表示小消息 u.vsm.flags = 0; u.vsm.size = (unsigned char) size_; } else { // 大消息 u.lmsg.type = type_lmsg; u.lmsg.flags = 0; u.lmsg.content = (content_t*) malloc (sizeof (content_t) + size_); // size_就是可变长的消息大小 if (!u.lmsg.content) { errno = ENOMEM; return -1; } u.lmsg.content->data = u.lmsg.content + 1; // 指向那块可变长的内存区域 u.lmsg.content->size = size_; u.lmsg.content->ffn = NULL; u.lmsg.content->hint = NULL; new (&u.lmsg.content->refcnt) zmq::atomic_counter_t (); // 设置引用计数 } return 0;}
int zmq::msg_t::init () // 消息初始化函数{ u.vsm.type = type_vsm; // 初始化一个msg消息,设置成小消息类型 u.vsm.flags = 0; // 初始化flags u.vsm.size = 0; // 将小消息的大小初始化为0 return 0; }
根据已有的data和相应的size,和销毁函数,以及hint来初始化消息。这边消息指向data指针所指的内存区域int zmq::msg_t::init_data (void *data_, size_t size_, msg_free_fn *ffn_, void *hint_) { u.lmsg.type = type_lmsg; u.lmsg.flags = 0; u.lmsg.content = (content_t*) malloc (sizeof (content_t)); if (!u.lmsg.content) { errno = ENOMEM; return -1; } u.lmsg.content->data = data_; u.lmsg.content->size = size_; u.lmsg.content->ffn = ffn_; u.lmsg.content->hint = hint_; new (&u.lmsg.content->refcnt) zmq::atomic_counter_t (); return 0; }
// 获取数据的地址的函数,这样就能操作消息的数据内存了void *zmq::msg_t::data (){ // Check the validity of the message. zmq_assert (check ()); switch (u.base.type) { case type_vsm: // 如果是小消息,就返回stack上的vsm_data的地址 return u.vsm.data; case type_lmsg: // 如果是大消息,就返回heap上的content->data return u.lmsg.content->data; default: //如果是delimiter,返回是空指针 zmq_assert (false); return NULL; }}
// 处理方式和data()类似,返回消息的大小size_t zmq::msg_t::size (){ // Check the validity of the message. zmq_assert (check ()); switch (u.base.type) { case type_vsm: return u.vsm.size; case type_lmsg: return u.lmsg.content->size; default: zmq_assert (false); return 0; }
// 销毁消息int zmq::msg_t::close (){ // Check the validity of the message. if (unlikely (!check ())) { errno = EFAULT; return -1; } if (u.base.type == type_lmsg) { // 如果不是共享的,或是引用计数为0,销毁它,销毁过程如下: // If the content is not shared, or if it is shared and the reference // count has dropped to zero, deallocate it. if (!(u.lmsg.flags & msg_t::shared) || !u.lmsg.content->refcnt.sub (1)) { // 1、销毁引用计数,因为创建引用计数的时候,我们使用placement new,所以我们需要调用它的析构函数。 // We used "placement new" operator to initialize the reference // counter so we call the destructor explicitly now. u.lmsg.content->refcnt.~atomic_counter_t (); // 2、如果有注册相应的自定义的销毁函数,就调用该函数。 // 这种情况主要用于使用init_data(),自己来管理data所指向空间。 if (u.lmsg.content->ffn) u.lmsg.content->ffn (u.lmsg.content->data, u.lmsg.content->hint); // 3、调用free()释放heap的空间,注意,如果是使用init_size()来初始化消息,就会释放掉data的空间, // 因为这块空间就是分配时多分配的size大小(在content下方)的那块 free (u.lmsg.content); } } // Make the message invalid. u.base.type = 0; // 设置为0,表明该消息已经被废除了 return 0;}// 对于小消息,消息数据是分配在stack上的,因此不需要手动销毁// 对于大消息,消息数据是分配在heap上的,因此我们查看消息是不是shared模式,如果没有使用就直接销毁假如使用了共享模式,那么我们递减消息的引用计数,一旦引用计数为0,我们就销毁消息内容。
int zmq::msg_t::copy (msg_t &src_){ // Check the validity of the source. if (unlikely (!src_.check ())) { errno = EFAULT; return -1; } int rc = close (); if (unlikely (rc < 0)) return rc; if (src_.u.base.type == type_lmsg) { // One reference is added to shared messages. Non-shared messages // are turned into shared messages and reference count is set to 2. if (src_.u.lmsg.flags & msg_t::shared) // 共享消息content引用,引用计数增加 src_.u.lmsg.content->refcnt.add (1); else { src_.u.lmsg.flags |= msg_t::shared; src_.u.lmsg.content->refcnt.set (2);// 如果不是共享的,则设置成共享的,并将引用计数设置成2 } } *this = src_; return 0;}
int zmq::msg_t::move (msg_t &src_){ // Check the validity of the source. if (unlikely (!src_.check ())) { errno = EFAULT; return -1; } int rc = close (); if (unlikely (rc < 0)) return rc; *this = src_; rc = src_.init (); // 将source的消息充值成初始化的空消息 if (unlikely (rc < 0)) return rc; return 0;}
0 0
- zmq源码阅读——Msg.hpp & Msg.cpp 的 相关操作 (zmq中的消息)
- zeromq源码阅读 —— Msg.hpp & Msg.cpp 的 msg_t (zmq中的消息)
- ZMQ源码分析(四)--MSG
- zmq源码阅读 —— zmq_send()和zmq_recv()
- 消息队列(msg)
- ZMQ源码分析(三)--对象管理和消息机制
- ZMQ——VS2012
- ZMQ
- ZMQ
- ZMQ
- ZMQ——注意的问题
- cpp bind zmq
- zmq以及c/cpp for zmq
- ZMQ——多线程通信(过程)
- MSG
- MSG
- msg
- ZeroMQ,史上最快的消息队列 —– ZMQ的学习和研究
- 使用uploadPreview插件上传文件并且预览
- [文件系统]文件系统学习笔记(十一)——mount系统调用(其它)
- 黑马程序员_7k面试题学习笔记
- arm-linux的gdb移植
- Biorhythms(数论)
- zmq源码阅读——Msg.hpp & Msg.cpp 的 相关操作 (zmq中的消息)
- SVN操作
- android闪屏效果实现
- 【学习记录】面向对象的基本概念5
- CentOS6.4下Mysql数据库的安装与配置
- 便不由自主的朝她所在的方向走去,
- 克隆管理员代码
- Myeclipse项目名为什么会带'>'和IP
- 常用的可变字符串处理实例方法 API文档 NSMutableString