Bug 2842 - Extend ACE_ALLOCATION_HOOKS
Summary: Extend ACE_ALLOCATION_HOOKS
Status: NEW
Alias: None
Product: ACE
Classification: Unclassified
Component: ACE Core (show other bugs)
Version: 5.5.6
Hardware: All All
: P3 normal
Assignee: Abdul Sowayan
URL:
Depends on:
Blocks: 2941
  Show dependency tree
 
Reported: 2007-03-02 09:28 CST by Abdul Sowayan
Modified: 2007-05-23 14:36 CDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Abdul Sowayan 2007-03-02 09:28:16 CST
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
Comment 1 Abdul Sowayan 2007-03-02 09:28:46 CST
Hi Abdul,

I think these are not maintained and tested for years. 

Johnny 
Comment 2 Abdul Sowayan 2007-03-02 09:29:28 CST
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
Comment 3 Abdul Sowayan 2007-03-02 09:29:43 CST
Hi Folks,

   We should probably zap these macros - I don't think they are meaningful 
anymore.
   
   Doug
Comment 4 Abdul Sowayan 2007-03-02 09:29:57 CST
Hi,

If you can provide the patches to add the missing methods that would be great.

Johnny
Comment 5 Abdul Sowayan 2007-03-02 09:30:18 CST
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 
Comment 6 Abdul Sowayan 2007-03-02 09:30:32 CST
Hi Johnny,

   I vote for ZAP!
   
   Doug
Comment 7 Abdul Sowayan 2007-03-02 09:31:12 CST
Hi,

ZAP it is then ;-) I was trying to understand what purpose they serve.

Thanks,
Abdul 
Comment 8 Abdul Sowayan 2007-03-02 09:32:51 CST
Hi,

I double check this with Steve Huston, if he agrees I will zap them.

Johnny 
Comment 9 Abdul Sowayan 2007-03-02 11:51:14 CST
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
Comment 10 Abdul Sowayan 2007-03-02 11:54:00 CST
Prior post was from JR Andreassen [janrune@io.com]
Comment 11 Abdul Sowayan 2007-03-02 14:17:11 CST
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
Comment 12 Abdul Sowayan 2007-03-02 14:17:34 CST
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
Comment 13 Johnny Willemsen 2007-03-05 03:54:40 CST
with the input from JT I think these macros should be fixed and extended instead
of removed
Comment 14 Abdul Sowayan 2007-03-05 08:56:56 CST
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
Comment 15 Johnny Willemsen 2007-03-05 08:59:03 CST
My remark was about JR's input, sorry, not JT
Comment 16 Abdul Sowayan 2007-03-05 09:04:11 CST
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
Comment 17 Abdul Sowayan 2007-03-05 09:04:46 CST
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
Comment 18 Johnny Willemsen 2007-03-08 04:50:56 CST
Abdul, can you add the missing variants?
Comment 19 Abdul Sowayan 2007-03-08 09:00:56 CST
Johnny,

Sure, I'll take care of this one.

Thanks,
Abdul
Comment 20 Johnny Willemsen 2007-03-08 09:04:30 CST
Changed summary