前面兩篇部落格講了從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