|
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.
|