天天看點

重拾cgi——uri綁定

前面兩篇部落格講了從uri到模闆輸出,還沒有提到中間處理參數的部分。

首先,參數綁定簡單的放在一個map中,這裡用的是boost的unordered_map(也就是hashmap),其實已經可以使用c++11提供的unordered_map了。

[cce lang=”cpp”]

boost::unordered::unordered_map<std::string, requesthandlefunc> _mapping;

[/cce]

這個map的value,是一個functor,具體定義為:

typedef boost::function<void (context &context)> requesthandlefunc;

也就是沒有傳回值,參數是context的函數。

context結構非常簡單,主要是封裝了輸入和輸出,也就是cgi、ostream、dict等對象,沒有進行太多的抽象。

struct context

{

cgicc::cgicc &cgi;

cgicc::cgiinput &input;

std::ostream &ostream;

boost::shared_ptr<ctemplate::templatedictionary> dict;

};

這裡增加了cgiinput,主要是因為cgicc封裝了常用cgi環境變量,沒法取到自定義環境變量(前一篇部落格介紹過)。

綁定函數非常簡單,就是直接插入,需要注意的是,unordered_map非線程安全,沒有線程類似java的concurrent hashmap(google了下intel tbb庫有類似的資料結構),是以采用了boost thread庫中的互斥變量:

void bind(const std::string &path, requesthandlefunc func)

boost::unique_lock<boost::shared_mutex> lock(_mutex);

_mapping.insert(std::pair<std::string, requesthandlefunc>(path, func));

}

注意,boost的鎖分為unique_lock和shared_lock,這裡是“寫者”,是以需要獨占鎖。

處理方法前文已經貼了代碼了,同樣要注意的是,需要在搜尋map的時候加鎖。這裡是“讀者”,是以使用shared_lock即可:

boost::shared_lock<boost::shared_mutex> lock(_mutex);

為了友善綁定,寫了個宏,直接綁定。

#define register_url(url, class, method) \

class c##class; handler::instance().bind(url, boost::bind(&class::method, &c##class, _1))

轉載自:https://coolex.info/blog/351.html