Please report new issues athttps://github.com/DOCGroup
ALLOCATION HOOKS are defined in config-macros.h, which can be found below # if defined (ACE_HAS_ALLOC_HOOKS) # define ACE_ALLOC_HOOK_DECLARE \ void *operator new (size_t bytes); \ void operator delete (void *ptr); // Note that these are just place holders for now. Some day they // may be be replaced by <ACE_Malloc>. # define ACE_ALLOC_HOOK_DEFINE(CLASS) \ void *CLASS::operator new (size_t bytes) { return ::new char[bytes]; } \ void CLASS::operator delete (void *ptr) { delete [] ((char *) ptr); } Shouldn't we add the nothrow varients of new and delete, and also placement- new? There is a whole item in the following book that discusses this in detail: Exceptional C++ Style 40 New Engineering Puzzles, Programming Problems, and Solutions By Herb Sutter, Item 22. So what we might have might look like (pseudo-code): // plain new void* CLASS:operator new(size_t bytes) { return ::operator new(bytes); } // placement-new void* CLASS::operator new(std::size_t bytes, void* p) throw() { return ::operator new(bytes, p); } // placement-new, non-throwing varient (with ACE_nothrow_t) /* not here */ void* CLASS::operator new(std::size_t bytes, const ACE_nothrow_t& n) throw() { return ::operator new(bytes, n); } void CLASS::operator delete(void *ptr) { ::operator delete ptr; } // operator delete, non-throwing varient with ACE_nothrow_t /* not here */ Of course we'd need to use ACE_HAS_NEW_NOTHROW and ACE_LACKS_PLACEMENT_OPERATOR_DELETE, etc macros to be more portable. The above are my initial thoughts/observations when I first came across the ALLOCATION_HOOKS today. I wanted to know what you folks think of this. If it is a legitimate concern, I can put this in Bugzilla. Thanks, Abdul
Hi Abdul, I think these are not maintained and tested for years. Johnny
Hi Johnny, I first came across ACE_ALLOCATION_HOOKS in Containers_T.h/cpp, I don't know how widely they are used in ACE. But there is an example below: template <class T> class ACE_Bounded_Stack { /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; } I think the purpose of ACE_ALLOC_HOOK_DECLARE is that under some platforms (such as Windows), dynamic memory allocated in a dll must be deallocated in the same dll. ACE_ALLOC_HOOK_DECLARE centralizes where dynamic memory allocation/deallocation for a given class. Am I right? I found an online version of the article by Herb Sutter I mentioned in an earlier email. It can be found in: http://www.gotw.ca/publications/mill15.htm In it, he argues that if you provide a class specific new, then you should provide the others, and if you don't, certain problems can occur. Thanks, Abdul
Hi Folks, We should probably zap these macros - I don't think they are meaningful anymore. Doug
Hi, If you can provide the patches to add the missing methods that would be great. Johnny
Hi, I am not 100% sure why they are there and if they are used. I don't think they are maintained much. If we can zap them it would be the easiest soltuion
Hi Johnny, I vote for ZAP! Doug
Hi, ZAP it is then ;-) I was trying to understand what purpose they serve. Thanks, Abdul
Hi, I double check this with Steve Huston, if he agrees I will zap them. Johnny
Hi... Just to add my 2 cents to the this conversation. I use ACE under Windows as lodable module DLL's(netsvc) and had helluva time with the forementioned dll dealoc issues. I had to implement the new/delete for all my classes. I didn't know about "ACE_ALLOCATION_HOOKS" So I did it this way: /////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) # ifndef SDI_ACE_UTILS_STATIC // Disable <warning C4251: 'm_vListnableList' : class 'std::deque<class SDI::Listnable *,class std::allocator<class SDI::Listnable *> >' needs to have dll-interface to be used by clients of class 'SDI::Listner'> # pragma warning(disable:4251) # if defined(SDI_ACE_UTILS_EXPORTS) # define SDIACE_EXPORT __declspec(dllexport) # else # define SDIACE_EXPORT __declspec(dllimport) # endif # else # define SDIACE_EXPORT # endif #else # define SDIACE_EXPORT #endif //#define USE_ACE_MEM_ALOCATOR #ifdef USE_ACE_MEM_ALOCATOR # define ACE_ALLOCATOR_INSTANCE ACE_Allocator::instance() #else # define ACE_ALLOCATOR_INSTANCE NULL #endif // ---------------------------------------------------------------- extern SDIACE_EXPORT UCHAR g_uNSDebugLevel; extern SDIACE_EXPORT void setDebugLevel(UCHAR level); // ********************** // ------------------------------------------------------------------------------- - SDIACE_EXPORT void* operator_new(size_t n); SDIACE_EXPORT void* operator_new(size_t n, const char* debFile, int debLine); SDIACE_EXPORT void operator_delete(void* p, const char* debFile, int debLine); SDIACE_EXPORT void operator_delete(void* p); #if defined (ACE_HAS_NEW_NOTHROW) SDIACE_EXPORT void* operator_new(size_t n, const ACE_nothrow_t& nothrow); SDIACE_EXPORT void* operator_new(size_t n, const ACE_nothrow_t& nothrow, const char* debFile, int debLine); SDIACE_EXPORT void operator_delete(void* p, const ACE_nothrow_t& nothrow, const char* debFile, int debLine); SDIACE_EXPORT void operator_delete(void* p, const ACE_nothrow_t& nothrow); #endif // ------------------------------------------------------------------------------- - #if defined (ACE_HAS_NEW_NOTHROW) #define DECLARE_INLINE_NEW_DELETE_OPERATORS_SDI_ACE \ void* operator new(size_t n, void* )\ { return SDI::ACE_Utils::operator_new(n, __FILE__, __LINE__); };\ void operator delete(void* p)\ { SDI::ACE_Utils::operator_delete(p, __FILE__, __LINE__); };\ void operator delete(void* p, void* p2)\ { SDI::ACE_Utils::operator_delete(p, __FILE__, __LINE__); };\ void* operator new(size_t n, const char* debFile = NULL, int debLine = 0)\ { return SDI::ACE_Utils::operator_new(n, debFile, debLine); };\ void operator delete(void* p, const char* debFile, int debLine)\ { SDI::ACE_Utils::operator_delete(p, debFile, debLine); };\ void* operator new(size_t n, const ACE_nothrow_t& nothrow)\ { return SDI::ACE_Utils::operator_new(n, nothrow, NULL, 0); };\ void* operator new(size_t n, const ACE_nothrow_t& nothrow, const char* debFile, int debLine)\ { return SDI::ACE_Utils::operator_new(n, nothrow, debFile, debLine); };\ void operator delete(void* p, const ACE_nothrow_t& nothrow, const char* debFile, int debLine)\ { SDI::ACE_Utils::operator_delete(p, debFile, debLine); };\ void operator delete(void* p, const ACE_nothrow_t& nothrow)\ { SDI::ACE_Utils::operator_delete(p, THIS_FILE, __LINE__); }; #else #define DECLARE_INLINE_NEW_DELETE_OPERATORS_SDI_ACE \ void* operator new(size_t n, void* )\ { return SDI::ACE_Utils::operator_new(n, __FILE__, __LINE__); };\ void operator delete(void* p)\ { SDI::ACE_Utils::operator_delete(p, __FILE__, __LINE__); };\ void operator delete(void* p, void* p2)\ { SDI::ACE_Utils::operator_delete(p, __FILE__, __LINE__); };\ void* operator new(size_t n, const char* debFile = NULL, int debLine = 0)\ { return SDI::ACE_Utils::operator_new(n, debFile, debLine); };\ void operator delete(void* p, const char* debFile, int debLine)\ { SDI::ACE_Utils::operator_delete(p, debFile, debLine); }; #endif // ------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------- - // New and delete operators // DECLARE_INLINE_NEW_DELETE_OPERATORS_SDI_ACE // ------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------- - #define DEFAULT_POLLER_HIGHWATER_MARK 2048000 #define ACE_QUEUE_FULL_RETURN_VALUE -99 #define ACE_UNGETQUEUE_RETURN_VALUE -98 #define ACE_BAD_RETURN_VALUE -1 #define ACE_GOOD_RETURN_VALUE 0 #define ACE_IS_GOOD_RETURN_STATUS(x) ((x) > ACE_BAD_RETURN_VALUE) #define IS_GOOD_ENQUEUE_RETURN(x) ((x) > ACE_BAD_RETURN_VALUE) // -------------------------------- #define ACE_RELEASE_BLOCK(x)\ { if(!ISNULL(x))\ { /*x->release(); */\ SDI::ACE_Utils::releaseMessageBlock(x);\ x = NULL;\ }\ } // -------------------------------- #define RELEASE_MDB(x, file, line)\ { if(!ISNULL(x))\ { x->release(file, line);\ x = NULL;\ }\ } ... // ------------------------------------------------------------------ // ------------------------------------------------------------------ class SDIACE_EXPORT SDI_ACE_Message_Block :public ACE_Message_Block { typedef ACE_Message_Block super; public: // = Initialization and termination. /// Create an empty message. SDI_ACE_Message_Block (ACE_Allocator *message_block_allocator = 0) :super(message_block_allocator) {}; SDI_ACE_Message_Block (ACE_Data_Block * mb, Message_Flags flags = 0, ACE_Allocator *message_block_allocator = 0) :super(mb, flags, message_block_allocator) {}; SDI_ACE_Message_Block (const char *data, size_t size = 0, unsigned long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY) :super(data, size, priority) {}; SDI_ACE_Message_Block (size_t size, ACE_Message_Type type = MB_DATA, ACE_Message_Block *cont = 0, const char *data = 0, ACE_Allocator *allocator_strategy = 0, ACE_Lock *locking_strategy = 0, unsigned long priority = ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY, const ACE_Time_Value &execution_time = ACE_Time_Value::zero, const ACE_Time_Value &deadline_time = ACE_Time_Value::max_time, ACE_Allocator *data_block_allocator = 0, ACE_Allocator *message_block_allocator = 0) :super(size, type, cont, data, allocator_strategy, locking_strategy, priority, execution_time, deadline_time, data_block_allocator, message_block_allocator) {}; SDI_ACE_Message_Block (const ACE_Message_Block &mb, size_t align) :super(mb, align) {}; virtual ~SDI_ACE_Message_Block() {}; // ------------------------------------------- DECLARE_INLINE_NEW_DELETE_OPERATORS_SDI_ACE // ------------------------------------------- }; /////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// JR
Prior post was from JR Andreassen [janrune@io.com]
JR, Assuming your ran generate_export_file.pl Foo, I think all you would've had to do is something like this: // header file #include "Foo_export.h" class Foo_Export Foo { public: ACE_ALLOC_HOOK_DECLARE }; // cpp file ACE_ALLOC_HOOK_DEFINE(Foo) Thanks, Abdul
Hi... Yes, I believe you're right. That's the problem with a library this size and the number of options. I''ve been working with ACE for a couple of years and discover new features all the time :) JR
with the input from JT I think these macros should be fixed and extended instead of removed
Johnny, Can you put JT's input into Bugzilla? I didn't find it in the user's group, so I'm assuming this discussion occured at the devo group. THanks, Abdul
My remark was about JR's input, sorry, not JT
Abdul, can you add the missing variants?
Johnny, Sure, I'll take care of this one. Thanks, Abdul
Changed summary