/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) // // See accompanying file COPYING.TXT file for licensing details. // /////////////////////////////////////////////////////////////////////////////// #define CPPCMS_SOURCE #include "session_memory_storage.h" #include #include "hash_map.h" #include #include #include namespace cppcms { namespace sessions { class session_memory_storage : public session_storage { struct _data; typedef cppcms::impl::hash_map< std::string, _data, cppcms::impl::string_hash > map_type; typedef map_type::iterator pointer; typedef std::multimap timeout_type; struct _data { time_t timeout; std::string info; timeout_type::iterator timeout_ptr; }; map_type map_; timeout_type timeout_; booster::shared_mutex mutex_; public: void save(std::string const &key,time_t to,std::string const &value) { booster::unique_lock lock(mutex_); pointer p=map_.find(key); if(p==map_.end()) { std::pair pr = map_.insert(std::pair(key,_data())); pointer p = pr.first; p->second.timeout=to; p->second.info=value; p->second.timeout_ptr=timeout_.insert(std::pair(to,p)); } else { timeout_.erase(p->second.timeout_ptr); p->second.timeout=to; p->second.info=value; p->second.timeout_ptr=timeout_.insert(std::pair(to,p)); } short_gc(); } void short_gc() { time_t now=::time(0); timeout_type::iterator p=timeout_.begin(),tmp; int count = 0; while(p!=timeout_.end() && p->first < now && count < 5) { tmp=p; ++p; map_.erase(tmp->second); timeout_.erase(tmp); count++; } } bool load(std::string const &key,time_t &to,std::string &value) { booster::shared_lock lock(mutex_); map_type::iterator p=map_.find(key); if(p==map_.end()) return false; if(p->second.timeout < ::time(0)) return false; value=p->second.info; to=p->second.timeout; return true; } void remove(std::string const &key) { booster::unique_lock lock(mutex_); pointer p=map_.find(key); if(p==map_.end()) return; timeout_.erase(p->second.timeout_ptr); map_.erase(p); short_gc(); } bool is_blocking() { return false; } }; session_memory_storage_factory::session_memory_storage_factory() : storage_(new session_memory_storage()) { } session_memory_storage_factory::~session_memory_storage_factory() { } booster::shared_ptr session_memory_storage_factory::get() { return storage_; } bool session_memory_storage_factory::requires_gc() { return false; } void session_memory_storage_factory::gc_job() { } } // sessions } // cppcms