之前就有计划优化游戏服务器框架网关层的内部协议了,这次泰国旅游回来,新公司入职前,正海有空来做这件事。

加密协商

以前提到过,最初决定重构这个流程是因为我觉得之前的方法,如果以后要扩展新的算法的话非常的麻烦。而后我看了一下shadowsocksr对多种加解密算法的实现方法,觉得还不错。就打算用类似的方法重写一下。当然也是因为写第一版的时候没考虑太多关于加解密方面的细节,还是优先实现出工程上可用的东西。这次就先稍微深入看了下像opensslmbedtls的一些实现,特别是下面会提到的cipher的实现。并以这个为基础来实现以后可能的增加加密算法的扩展。

上个月,同学的公司,格奕,突然间跪了。这个月基本属于休息+四处溜达。同时空闲的时候也想整理下之前做得一些之前的做得一些小工具们。在不泄密的情况下开源出来吧(其实也就是想找github存放一下而已,也没什么特别NB的东西)。

其实很早就想把Blog迁移到静态化的博客系统了。不过一直没花时间来搞,当然主要原因还是懒。

这次下决心搞主要是因为,之前VPS迁移到Vultr,然后它的主机默认是没有交换区的。后来老是收到网站崩溃告警,每次去看都是MariaDB挂掉了,然后查了一下是内存不足。 然后,调整了几次参数,发现都不能解决问题。我这么个小站搞个高配机器显然是浪费。这种小网站都能耗尽1GB的内存我也是醉了。所以后来就干脆迁移到静态博客系统算了。

线程安全

前段时间看到了一个完成读比较高的协程库-libgo,里面提供了线程安全的协程实现,并且也是使用锁。本来我并没有给libcopp里的功能加锁的打算,因为上层dispatcher还是比较容易做到安全分发的,所以原来并不保证线程安全。而且线程安全这种问题单元测试比较难写,可能还得碰点运气。但是思来想去,还是为线程安全做点什么吧。反正也不是很复杂。

由于我并没有给utils加互斥锁的跨平台适配,所以先就直接用了自旋锁,来锁住需要考虑线程安全的地方。其实需要加锁的地方并不多,无非是管理器的增删查和task的next函数需要加锁。这些逻辑都很短,功能也很简单,并不会占用太多时间,所以自旋锁的问题也不大。而且以后真发现有问题,换掉也不是什么难事儿。

又好久没写blog啦。诶最近好懒啊。正好过年在家里有点空,写完我那些lib的patch之后还有一点时间写一下2016年的总结吧。

之前两年的总结有点流水账,我还是写得随意一点好了,也没必要凑字数。

之前我的域名只有owent.net和www.owent.net买了SSL证书,现在有letsencrypt可以拿到免费的SSL签证,就稍微花了点时间把我的域名的其他部分接入了letsencrypt签证系统。另外根据其他人的一些配置建议,提高了HTTPS的安全性配置和性能配置(主要是缓存)。另外原本我的blog就已经启用了spdy,然而现在新版本的nginx1.10)已经release,原先的spdy模块被取消,新增了http/2模块。但是直接换nginx掉包是不行滴(后面有说原因),所以顺带自己处理了一下HTTP/2和nginx新版本的问题。

并且也对公司里的域名和webserver也这么搞了一下。全面启用HTTPS。

使用_Markdown_写blog已经很久了,近期接触并且看了下流传已久的gitbook平台,感觉做得确实不错。、

之前写blog的时候一直用得是stackedit,是因为stackedit的对_Markdown_做了很多扩展,功能很强大,有自动目录、流程图、时序图等等,然后可以浏览器直接开很方便。但实际上这些功能写出的东西虽然不错,但是放到比如github上的时候,github不支持。目前大多数平台对_Mardown_的扩展都只是到了和github差不多的地步,没有到stackedit的程度。这也导致同样写得东西,复制到github或者其他的平台的时候还得过一遍样式,比较麻烦。而且这些扩展的功能也用得不太多。另外stackedit时不时被墙然后访问很不稳定也是挺麻烦的一件事儿。

再来说这个gitbook,看中他是觉得它做了一个可持续集成的功能。就是github _push_完以后可以通知gitbook然后让gitbook自动构建文档内容。这点和比如jenkinstravis等等的CI系统很像。然后支持构建成pdf、epub(开源电子书格式)、mobi(kindle电子书格式)和在线书籍。然后版式也挺漂亮,还支持模板,引用等等,感觉确实蛮适合出版发行的。虽然目前为止_Markdown_的功能丰富程度比起Latex还差不少,但是上手难度也比Latex低不少。还是非常有潜力的,而且gitbook支持用javascript写得插件,以后变数也可以很多。

近期的活动比较零散,主要的业余精力都放在了libatbus上了。但是这个一时半会也写不完,所以能整理出来的东西不多。就说下最近跟进的开源代码吧。

首先是,跨平台协程框架 libcopp 跟进merge了boost 1.60 的context组件,这部分改动不多。仅仅是例行合并。

接上文

目录

BUS系统的设计思路

虽然我很不愿意再设计一套BUS系统,但是现有的一些确实都没有特别符合我的口味的。所以还是尝试设计一个出来。

结构设计

简单来说,我希望BUS系统可以简单、高效、稳定。

目录

概述

如何保证一个进程或线程能安全稳定地把一段消息发送到另一个进程和线程,甚至是另一台机器的进程或线程,再或是要通过代理转发到另一个进程或线程,一直是一个比较麻烦的问题。

目录

C++ 的Lambda表达式

C++ 11 标准发布,各大编译器都开始支持里面的各种新特性,其中一项比较有意思的就是lambda表达式。

语法规则

C++ 11 Lambda表达式的四种声明方式

C++11标准里有动态模板参数已经是众所周知的事儿了。但是当时还有个主流编译器还不支持。 但是现在,主要的编译器。VC(Windows),GCC(Windows,Linux),Clang(Mac,IOS)都已经支持了。所以就可以准备用于生产环境了。 type_traits没啥好说的。主要是一些静态检测。主要还是要看动态模板参数和他们两的结合使用上。 动态模版参数标准文档见: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdfhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf 虽然贴出来了。估计是没人看得。所以就直接说重点。

前几天我们项目的日志系统出现了一点问题,但是一直没有时间去深究。 昨天在同事的帮助下,无意中猜了一种可能性,结果还真被我猜中了,于是今天就特别研究了一下,记录下来。

项目里面引入了Lua,就特别学习了一下。

其实对于理解Javascipt的人来说,Lua也很容易理解,因为他们太多的地方相像了。

初步看来,Lua的设计模式和思想很像Javascript,也是原型模型(Javascript里叫prototype,Lua里是metatable

接上一篇 VC和GCC内成员函数指针实现的研究(二)

虚继承

终于到最后的虚继承了。

测试代码如下:

#include <ctime>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <stdint.h>
#include <cstddef>
#include <string>

class foo_a
{
public:
    virtual ~foo_a(){}
    virtual void info() {
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    }

    void print(){
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    }
};

class foo_l
{
public:
    int l;
    foo_l(): l(1){}

    virtual void info() {
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    }
};

class foo_r: virtual public foo_a
{
public:
    int r;
    foo_r(): r(2){}
};

class foo_c: virtual public foo_l, public foo_r
{
public:
    virtual void info() {
        printf("%d,%d. %s:%d\n", l, r, __FUNCTION__, __LINE__);
    }
};


int main(int argc, char* argv[]) {
    void (foo_a::*vptr1)() = &foo_a::info;
    void (foo_l::*vptr2)() = &foo_l::info;
    void (foo_a::*ptr)() = &foo_a::print;

    foo_c c;
    foo_r r;
    foo_a a;

    printf("pword size = %d\n", (int)(sizeof(size_t)));
    printf("address of &foo_a::info = 0x%llxH\n", &foo_a::info);
    printf("pointer to &foo_a::info = 0x%llxH\n", vptr1);
    printf("sizeof vptr = %d\n", (int)(sizeof(vptr1)));

    (a.*vptr1)();
    (r.*vptr1)();
    (c.*vptr1)();
    (c.*vptr2)();
    c.info();

    (c.*ptr)();

    return 0;
}

VC虚继承成员函数指针实现

因为是兼容虚继承和非虚继承的,所以赋值的部分的汇编是一样的。这里就不贴了。关键在于执行期它是怎么找到虚基类的。请往下看:

接上一篇 VC和GCC内成员函数指针实现的研究(一)

接下来是多重继承,用到的测试代码如下所示:

#include <ctime>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <stdint.h>
#include <cstddef>
#include <string>

class foo_a
{
public:
    virtual ~foo_a(){}
    virtual void info() {
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    }
};

class foo_b
{
public:
    virtual ~foo_b(){}

    // 这个函数用于试foo_b的结构与foo_a不同
    // 以防止VC对foo_a和foo_b的`vcall'{8}'的代码合并
    virtual void inspect() { 
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    } 

    virtual void info() {
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    }

    void print() {
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    }
};


class foo_c: public foo_a, public foo_b
{
public:
    virtual void info() {
        printf("%s:%d\n", __FUNCTION__, __LINE__);
    }
};


int main(int argc, char* argv[]) {
    void (foo_a::*vptr1)() = &foo_a::info;
    void (foo_b::*vptr2)() = &foo_b::info;
    void (foo_b::*ptr)() = &foo_b::print;

    foo_c c;
    foo_b b;
    foo_a a;

    
    printf("word size = %d\n", (int)(sizeof(size_t)));
    printf("address of &foo_a::info = 0x%llxH\n", &foo_a::info);
    printf("pointer to &foo_a::info = 0x%llxH\n", vptr1);
    printf("address of &foo_b::info = 0x%llxH\n", &foo_b::info);
    printf("pointer to &foo_b::info = 0x%llxH\n", vptr2);
    printf("sizeof vptr = %d\n", (int)(sizeof(vptr1)));

    (a.*vptr1)();
    (b.*vptr2)();
    (c.*vptr1)();
    (c.*vptr2)();

    (c.*ptr)();

    return 0;
}

VC多重继承成员函数指针实现

最近在《C++对象模型》一书里说到的virtual的成员函数指针,低于128的被cfront编译器认为是虚表偏移量(支持子类对父类函数的覆盖)。VC只是提了下单继承、多继承和虚继承的实现方案不同,GCC没有提及,所以就专门稍微深入分析研究下他们的实现机制。