From: <arn...@us...> - 2007-12-31 20:15:40
|
Revision: 118 http://adchpp.svn.sourceforge.net/adchpp/?rev=118&view=rev Author: arnetheduck Date: 2007-12-31 12:15:30 -0800 (Mon, 31 Dec 2007) Log Message: ----------- Use memory pool again Modified Paths: -------------- adchpp/trunk/adchpp/Buffer.h adchpp/trunk/adchpp/ManagedSocket.cpp adchpp/trunk/adchpp/PluginManager.cpp adchpp/trunk/adchpp/PluginManager.h adchpp/trunk/adchpp/SocketManager.cpp adchpp/trunk/adchpp/Util.cpp adchpp/trunk/adchpp/Util.h adchpp/trunk/swig/adchpp.i adchpp/trunk/swig/lua.i adchpp/trunk/swig/python.i Added Paths: ----------- adchpp/trunk/adchpp/Buffer.cpp Added: adchpp/trunk/adchpp/Buffer.cpp =================================================================== --- adchpp/trunk/adchpp/Buffer.cpp (rev 0) +++ adchpp/trunk/adchpp/Buffer.cpp 2007-12-31 20:15:30 UTC (rev 118) @@ -0,0 +1,18 @@ +#include "adchpp.h" + +#include "Buffer.h" +#include "SettingsManager.h" + +namespace adchpp { + +Pool<ByteVector, Buffer::Clear> Buffer::free; + +void Buffer::Clear::operator()(ByteVector& v) { + if(v.capacity() > static_cast<size_t>(SETTING(BUFFER_SIZE))) { + ByteVector().swap(v); + } else { + v.clear(); + } +} + +} Modified: adchpp/trunk/adchpp/Buffer.h =================================================================== --- adchpp/trunk/adchpp/Buffer.h 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/adchpp/Buffer.h 2007-12-31 20:15:30 UTC (rev 118) @@ -1,6 +1,8 @@ #ifndef BUFFER_H_ #define BUFFER_H_ +#include "Pool.h" +#include "Util.h" #include "FastAlloc.h" namespace adchpp { @@ -10,29 +12,36 @@ */ class Buffer : public intrusive_ptr_base, public FastAlloc<Buffer> { public: - Buffer(const std::string& str) : buf((uint8_t*)str.data(), (uint8_t*)str.data() + str.size()) { } - Buffer(const void* ptr, const size_t size) : buf((uint8_t*) ptr, ((uint8_t*)ptr)+size) { } - Buffer(const size_t size) : buf(size) { } + Buffer(const std::string& str) : bufp(free) { append((uint8_t*)str.data(), (uint8_t*)str.data() + str.size()); } + Buffer(const void* ptr, const size_t size) : bufp(free) { append((uint8_t*) ptr, ((uint8_t*)ptr)+size); } + Buffer(const size_t size) : bufp(free) { resize(size); } + ~Buffer() { free = bufp; } - operator const ByteVector&() const { return buf; } - operator ByteVector&() { return buf; } + operator const ByteVector&() const { return buf(); } + operator ByteVector&() { return buf(); } - void resize(size_t new_size) { buf.resize(new_size); } - size_t size() const { return buf.size(); } - const uint8_t* data() const { return &buf[0]; } - uint8_t* data() { return &buf[0]; } + void resize(size_t new_size) { buf().resize(new_size); } + size_t size() const { return buf().size(); } + const uint8_t* data() const { return &buf()[0]; } + uint8_t* data() { return &buf()[0]; } /** Erase the first n bytes */ - void erase_first(size_t n) { - buf.erase(buf.begin(), buf.begin() + n); - } + void erase_first(size_t n) { buf().erase(buf().begin(), buf().begin() + n); } template<typename InputIterator> - void append(InputIterator start, InputIterator end) { - buf.insert(buf.end(), start, end); - } + void append(InputIterator start, InputIterator end) { buf().insert(buf().end(), start, end); } private: - ByteVector buf; + + const ByteVector& buf() const { return *bufp; } + ByteVector& buf() { return *bufp; } + + ByteVector* bufp; + + struct Clear { + ADCHPP_DLL void operator()(ByteVector& x); + }; + + ADCHPP_DLL static Pool<ByteVector, Clear> free; }; typedef boost::intrusive_ptr<Buffer> BufferPtr; Modified: adchpp/trunk/adchpp/ManagedSocket.cpp =================================================================== --- adchpp/trunk/adchpp/ManagedSocket.cpp 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/adchpp/ManagedSocket.cpp 2007-12-31 20:15:30 UTC (rev 118) @@ -42,19 +42,6 @@ ManagedSocket::~ManagedSocket() throw() { dcdebug("ManagedSocket deleted\n"); -#if 0 - if(outBuf) { - dcdebug("Left (%d): %.*s\n", outBuf->size(), outBuf->size(), &(*outBuf)[0]); - Util::freeBuf = outBuf; - } - -#ifdef _WIN32 - if(writeBuf) { - dcdebug("Left2 (%d): %.*s\n", writeBuf->size(), writeBuf->size(), &(*writeBuf)[0]); - Util::freeBuf = writeBuf; - } -#endif -#endif } void ManagedSocket::write(const BufferPtr& buf) throw() { Modified: adchpp/trunk/adchpp/PluginManager.cpp =================================================================== --- adchpp/trunk/adchpp/PluginManager.cpp 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/adchpp/PluginManager.cpp 2007-12-31 20:15:30 UTC (rev 118) @@ -52,6 +52,7 @@ namespace adchpp { using namespace std; +using namespace std::tr1; using namespace std::tr1::placeholders; PluginManager* PluginManager::instance = 0; @@ -65,6 +66,10 @@ } +void PluginManager::attention(const function<void()>& f) { + SocketManager::getInstance()->addJob(f); +} + bool PluginManager::loadPlugin(const string& file) { if(file.length() < 3) { return false; Modified: adchpp/trunk/adchpp/PluginManager.h =================================================================== --- adchpp/trunk/adchpp/PluginManager.h 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/adchpp/PluginManager.h 2007-12-31 20:15:30 UTC (rev 118) @@ -22,7 +22,7 @@ * * ADCH++ contains a rather powerful plugin API that can be used to create advanced * plugins that change or add to ADCH++'s behaviour. Most plugins will need - * PluginManager.h, ClientManager. and Client.h included to work, even though the + * PluginManager.h, ClientManager.h and Client.h included to work, even though the * other header files are available as well (they're more likely to change in future * versions though). You can use any method that is declared as DLL or is inline, the * others are meant to be internal to ADCH++, very likely to change/disappear and will @@ -36,13 +36,7 @@ * of the ADCH++ plugin API. This version usually follows the main ADCH++ version, * unless a small update is made that I judge shouldn't affect plugins in any way. * Most of the time, recompiling the plugin should be enough, unless any major changes - * have been made, and your plugin doesn't rely on the nasty internals. As to compilers, - * the windows version is compiled using Visual C++ 7.1 (.NET), with various optimizations - * enabled. In theory, VC6 should work as well, as I haven't seen any information about - * changes in the name mangling scheme, but if you get strange linker errors, don't - * blame me. For best results, make sure you have the same settings. The Linux version - * is compiled with G++ 3.4.x, and I don't have a clue if older versions will work - * (probably not...). + * have been made, and your plugin doesn't rely on the nasty internals. * * @section Threads Threads * @@ -50,19 +44,16 @@ * communication while the other does all other work (handle protocol data and * so on). All plugins are run in the worker thread, which is the only thread * visible to the API. You are only allowed to interact with ADCH++ from this - * thread, as none of the API is thread safe (this is a performance issue, this way - * no locks are taken), unless otherwise noted. This has a few important - * consequences. First off, you can assume that your plugin will only be called - * by this thread, which means that you don't have to worry about multithreading - * issues unless you start threads by yourself. Second, any work you do in a plugin - * halts <b>all</b> of ADCH++'s processing (apart from receiving/sending buffered - * data), in other words, don't do any lengthy processing in the on methods, as - * the whole of ADCH++ will suffer. Third, if you indeed start another thread, make + * thread, as none of the API is thread safe, unless otherwise noted. This has a + * few important consequences. First off, you can assume that your plugin will + * only be called by this thread, which means that you don't have to worry about + * multithreading issues unless you start threads by yourself. Second, any work you + * do in a plugin halts <b>all</b> of ADCH++'s processing (apart from receiving/sending + * buffered data), in other words, don't do any lengthy processing in the on methods, + * as the whole of ADCH++ will suffer. Third, if you indeed start another thread, make * sure you don't use any API functions from it apart from those explicitly marked * as thread safe. To indicate from a plugin that you have work to do in the main - * worker thread, call PluginManager::attention(). This will generate an - * Attention event in the near future, where your thread can do its work (be - * careful though, the Attention event might be raised by other plugins). + * worker thread, call PluginManager::attention(). */ #ifndef ADCHPP_PLUGINMANAGER_H @@ -147,6 +138,13 @@ typedef Registry::iterator RegistryIter; /** + * This is a thread-safe method to call when you need to perform some work + * in the main ADCH++ worker thread. Your job will be executed once, when + * time permits. + */ + ADCHPP_DLL void attention(const std::tr1::function<void()>& f); + + /** * Get a list of currently loaded plugins */ const StringList& getPluginList() const { @@ -174,7 +172,7 @@ * @return false if name was already registered and call fails */ bool registerPlugin(const std::string& name, Plugin* ptr) { - return registry.insert(std::make_pair(name, ptr)).second; + return registry.insert(std::make_pair(name, ptr)).second; } /** @return True if the plugin existed and was thus unregistered */ @@ -193,7 +191,7 @@ /** * The full map of registered plugins. */ - const Registry& getPlugins() { + const Registry& getPlugins() const { return registry; } Modified: adchpp/trunk/adchpp/SocketManager.cpp =================================================================== --- adchpp/trunk/adchpp/SocketManager.cpp 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/adchpp/SocketManager.cpp 2007-12-31 20:15:30 UTC (rev 118) @@ -578,7 +578,6 @@ ms->completeWrite(buffers, 0); return; } - //Util::freeBuf = writeBuf; disconnect(ms, error); return; } @@ -650,7 +649,7 @@ bool stop; - typedef unordered_set<ManagedSocketPtr, PointerHash<ManagedSocket> > SocketSet; + typedef unordered_set<ManagedSocketPtr> SocketSet; /** Sockets that have a pending read */ SocketSet active; /** Sockets that are being written to but should be disconnected if timeout it reached */ Modified: adchpp/trunk/adchpp/Util.cpp =================================================================== --- adchpp/trunk/adchpp/Util.cpp 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/adchpp/Util.cpp 2007-12-31 20:15:30 UTC (rev 118) @@ -63,7 +63,6 @@ string Util::cfgPath; size_t Util::reasons[REASON_LAST]; -Pool<ByteVector, Util::Clear> Util::freeBuf; static void sgenrand(unsigned long seed); @@ -74,14 +73,6 @@ setCfgPath(configPath); } -void Util::Clear::operator()(ByteVector& v) { - if(v.capacity() > static_cast<size_t>(SETTING(BUFFER_SIZE))) { - ByteVector().swap(v); - } else { - v.clear(); - } -} - /** * Decodes a URL the best it can... * Default ports: Modified: adchpp/trunk/adchpp/Util.h =================================================================== --- adchpp/trunk/adchpp/Util.h 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/adchpp/Util.h 2007-12-31 20:15:30 UTC (rev 118) @@ -22,6 +22,15 @@ #include "Pool.h" #include "Mutex.h" +namespace std { namespace tr1 { + +template<typename T> +struct hash<boost::intrusive_ptr<T> > { + size_t operator()(const boost::intrusive_ptr<T>& t) const { return hash<T*>()(t.get()); } +}; + +} } + namespace adchpp { struct intrusive_ptr_base { @@ -81,24 +90,6 @@ void operator()(T* ptr) { delete ptr; } }; -/** A generic hash for pointers */ -template<class T> -struct PointerHash { -#if _MSC_VER >= 1300 - static const size_t bucket_size = 4; - static const size_t min_buckets = 8; -#endif - size_t operator()(const T* a) const { return ((size_t)a)/sizeof(T); } - bool operator()(const T* a, const T* b) { return a < b; } - - size_t operator()(const boost::intrusive_ptr<T>& a) const { return ((size_t)a.get())/sizeof(T); } - bool operator()(const boost::intrusive_ptr<T>& a, const boost::intrusive_ptr<T>& b) { return a.get() < b.get(); } -}; -template<> -struct PointerHash<void> { - size_t operator()(const void* a) const { return ((size_t)a)>>2; } -}; - /** * Compares two values * @return -1 if v1 < v2, 0 if v1 == v2 and 1 if v1 > v2 @@ -307,12 +298,6 @@ /** Avoid this! Use the one of a connected socket instead... */ ADCHPP_DLL static std::string getLocalIp(); - struct Clear { - void operator()(ByteVector& x); - }; - /** Pool of free buffers */ - ADCHPP_DLL static Pool<ByteVector, Clear> freeBuf; - ADCHPP_DLL static uint32_t rand(); static uint32_t rand(uint32_t high) { return rand() % high; } static uint32_t rand(uint32_t low, uint32_t high) { return rand(high-low) + low; } Modified: adchpp/trunk/swig/adchpp.i =================================================================== --- adchpp/trunk/swig/adchpp.i 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/swig/adchpp.i 2007-12-31 20:15:30 UTC (rev 118) @@ -718,6 +718,8 @@ class PluginManager { public: + void attention(const std::tr1::function<void()>& f); + //typedef HASH_MAP<std::string, Plugin*> Registry; //typedef Registry::iterator RegistryIter; Modified: adchpp/trunk/swig/lua.i =================================================================== --- adchpp/trunk/swig/lua.i 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/swig/lua.i 2007-12-31 20:15:30 UTC (rev 118) @@ -42,6 +42,11 @@ LuaFunction(const LuaFunction& rhs) : L(rhs.L), registryItem(rhs.registryItem) { } LuaFunction& operator=(const LuaFunction& rhs) { L = rhs.L; registryItem = rhs.registryItem; return *this; } + void operator()() { + pushFunction(); + docall(0, 0); + } + void operator()(adchpp::Client& c) { pushFunction(); @@ -144,6 +149,10 @@ lua_pushnumber(L, (lua_Number)$1); SWIG_arg++; } +%typemap(in) std::tr1::function<void () > { + $1 = LuaFunction(L); +} + %typemap(in) std::tr1::function<void (adchpp::Client &) > { $1 = LuaFunction(L); } Modified: adchpp/trunk/swig/python.i =================================================================== --- adchpp/trunk/swig/python.i 2007-12-30 21:41:46 UTC (rev 117) +++ adchpp/trunk/swig/python.i 2007-12-31 20:15:30 UTC (rev 118) @@ -5,6 +5,9 @@ #undef socklen_t %} +%typemap(in) std::tr1::function<void ()> { + $1 = PyHandle($input, false); +} %typemap(in) std::tr1::function<void (adchpp::Client&)> { $1 = PyHandle($input, false); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |