-rw-r--r-- | lib/.gitignore | 7 | ||||
-rw-r--r-- | lib/Makefile.am | 16 | ||||
-rw-r--r-- | lib/exception.cc | 66 | ||||
-rw-r--r-- | lib/pointer_map.cc | 74 | ||||
-rw-r--r-- | lib/pqxx_pile.cc | 17 |
5 files changed, 180 insertions, 0 deletions
diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 0000000..7a5e754 --- a/dev/null +++ b/lib/.gitignore @@ -0,0 +1,7 @@ +Makefile.in +.libs +.deps +Makefile +*.lo +*.o +*.la diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..a904569 --- a/dev/null +++ b/lib/Makefile.am @@ -0,0 +1,16 @@ +lib_LTLIBRARIES = libkonforka.la + +INCLUDES = -I${top_srcdir}/include +AM_CXXFLAGS = ${PQXX_CFLAGS} +LDADD = ${PQXX_LIBS} + +EXTRA_DIST = pqxx_pile.cc +EXTRA_SOURCES= +if HAVE_PQXX +EXTRA_SOURCES += pqxx_pile.cc +endif + +libkonforka_la_SOURCES = \ + exception.cc \ + pointer_map.cc \ + ${EXTRA_SOURCES} diff --git a/lib/exception.cc b/lib/exception.cc new file mode 100644 index 0000000..65302bf --- a/dev/null +++ b/lib/exception.cc @@ -0,0 +1,66 @@ +#include <string.h> +#include <errno.h> +#include "konforka/exception.h" + +namespace konforka { + + /* + * code_point + */ + + code_point::code_point(const string& w) + : where(w), line(-1) { } + code_point::code_point(const string& fi,const string& fu,int l) + : file(fi), function(fu), line(l) { + make_where(); + } + + const char *code_point::c_str() const throw() { + return where.c_str(); + } + + void code_point::make_where() { + static char tmp[8]; + snprintf(tmp,sizeof(tmp),"%d",line); + where = file + ":" + tmp + " [" + function + "]"; + } + + /* + * exception + */ + + exception::exception(const string& whe,const string& wha) + : _where(whe), _what(wha) { } + exception::exception(const string& fi,const string& fu,int l,const string& w) + : _where(fi,fu,l), _what(w) { } + exception::~exception() throw() { } + + const char *exception::where() const throw() { + return _where.c_str(); + } + const char *exception::what() const throw() { + return _what.c_str(); + } + + void exception::see(const string& w) { + _seen.push_back(code_point(w)); + } + void exception::see(const string& fi,const string& fu,int l) { + _seen.push_back(code_point(fi,fu,l)); + } + + /* + * system_error + */ + + system_error::system_error(const string& whe,const string& wha) + : _errno(errno), exception(whe,wha) { } + system_error::system_error(const string& fi,const string& fu,int l,const string& w) + : _errno(errno), exception(fi,fu,l,w) { } + system_error::~system_error() throw() { } + + const char *system_error::why() const throw() { + return strerror(errno); // TODO: strerror_r + } + +} diff --git a/lib/pointer_map.cc b/lib/pointer_map.cc new file mode 100644 index 0000000..44f7ebc --- a/dev/null +++ b/lib/pointer_map.cc @@ -0,0 +1,74 @@ +#include <cassert> +#include <map> +#include <string> +using namespace std; +#include "konforka/exception.h" +#include "konforka/pointer_map.h" + +namespace konforka { + + /* + * to_t->from_t->from->to + */ + class mpointer_t { + public: + void *ptr; + int ref; + + mpointer_t() : ptr(0), ref(0) { } + + void _ref() { ref++; } + void _unref() { ref--; } + }; + typedef map<void*,mpointer_t> map_ptr_1_t; + typedef map<string,map_ptr_1_t> map_ptr_2_t; + typedef map<string,map_ptr_2_t> map_ptr_t; + + static map_ptr_t pointer_map; + + void _map_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt) { + mpointer_t& mpt = pointer_map[tf.name()][tt.name()][pf]; + if(mpt.ref) { + if(mpt.ptr != pt) + throw exception(CODEPOINT,"trying to remap existing pointer with different value"); + }else{ + mpt.ptr = pt; + } + mpt.ref++; + } + void _unmap_pointer(const type_info& tf,void *pf,const type_info& tt,void *pt) { + map_ptr_t::iterator i1 = pointer_map.find(tf.name()); + if(i1==pointer_map.end()) + throw exception(CODEPOINT,"no pointer of such type has ever been mapped"); + map_ptr_2_t::iterator i2 = i1->second.find(tt.name()); + if(i2==i1->second.end()) + throw exception(CODEPOINT,"no pointer has ever been mapped to the object of this type"); + map_ptr_1_t::iterator i3 = i2->second.find(pf); + if(i3==i2->second.end()) + throw exception(CODEPOINT,"this pointer has never been mapped"); + assert(i3->second.ref>0); + if(--(i3->second.ref)) + return; + i2->second.erase(i3); + if(!i2->second.empty()) + return; + i1->second.erase(i2); + if(!i1->second.empty()) + return; + pointer_map.erase(i1); + } + void *_mapped_pointer(const type_info& tf,void *pf,const type_info& tt) { + map_ptr_t::iterator i1 = pointer_map.find(tf.name()); + if(i1==pointer_map.end()) + throw exception(CODEPOINT,"no pointer of such type has ever been mapped"); + map_ptr_2_t::iterator i2 = i1->second.find(tt.name()); + if(i2==i1->second.end()) + throw exception(CODEPOINT,"no pointer has ever been mapped to the object of this type"); + map_ptr_1_t::iterator i3 = i2->second.find(pf); + if(i3==i2->second.end()) + throw exception(CODEPOINT,"this pointer has never been mapped"); + assert(i3->second.ref>0); + return i3->second.ptr; + } + +} diff --git a/lib/pqxx_pile.cc b/lib/pqxx_pile.cc new file mode 100644 index 0000000..d6623bb --- a/dev/null +++ b/lib/pqxx_pile.cc @@ -0,0 +1,17 @@ +#include "konforka/pqxx_pile.h" + +namespace konforka { + + template class resource_pile_generic_ptr_factory<string,pqxx::connection>; + template class resource_pile_generic_ptr_factory<string,pqxx::lazyconnection>; + template class resource_pile_generic_ptr_factory<string,pqxx::asyncconnection>; + + template class resource_pile_base<string,pqxx::connection*,resource_pile_generic_ptr_factory<string,pqxx::connection> >; + template class resource_pile_base<string,pqxx::lazyconnection*,resource_pile_generic_ptr_factory<string,pqxx::lazyconnection> >; + template class resource_pile_base<string,pqxx::asyncconnection*,resource_pile_generic_ptr_factory<string,pqxx::asyncconnection> >; + + template class pqxx_piled_connection_base<pqxx::connection>; + template class pqxx_piled_connection_base<pqxx::lazyconnection>; + template class pqxx_piled_connection_base<pqxx::asyncconnection>; + +} |