Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends

ACE_DLL_Manager Class Reference

This class is a singleton and serves as a factory and repository for instances of ACE_DLL_Handle. More...

#include <DLL_Manager.h>

Collaboration diagram for ACE_DLL_Manager:
Collaboration graph
[legend]

List of all members.

Public Types

enum  { DEFAULT_SIZE = ACE_DEFAULT_DLL_MANAGER_SIZE }

Public Member Functions

ACE_DLL_Handleopen_dll (const ACE_TCHAR *dll_name, int openmode, ACE_SHLIB_HANDLE handle)
int close_dll (const ACE_TCHAR *dll_name)
 Close the underlying dll. Decrements the refcount.
u_long unload_policy (void) const
 Returns the current per-process UNLOAD_POLICY.
void unload_policy (u_long unload_policy)

Static Public Member Functions

static ACE_DLL_Managerinstance (int size=ACE_DLL_Manager::DEFAULT_SIZE)
 Return a unique instance.

Protected Member Functions

 ACE_DLL_Manager (int size=ACE_DLL_Manager::DEFAULT_SIZE)
 Default constructor.
 ~ACE_DLL_Manager (void)
 Destructor.
int open (int size)
 Allocate handle_vector_.
int close (void)
 Close all open dlls and deallocate memory.
ACE_DLL_Handlefind_dll (const ACE_TCHAR *dll_name) const
 Find dll in handle_vector_.
int unload_dll (ACE_DLL_Handle *dll_handle, int force_unload=0)
 Applies strategy for unloading dll.

Private Member Functions

 ACE_DLL_Manager (const ACE_DLL_Manager &)
 Disallow copying and assignment since we don't handle these.
void operator= (const ACE_DLL_Manager &)

Static Private Member Functions

static void close_singleton (void)
 Close the singleton instance.

Private Attributes

ACE_DLL_Handle ** handle_vector_
 Vector containing all loaded handle objects.
int current_size_
 Current number of handles.
int total_size_
 Maximum number of handles.
u_long unload_policy_
 Unload strategy.

Static Private Attributes

static ACE_DLL_Managerinstance_ = 0
 Pointer to a process-wide ACE_DLL_Manager.

Friends

class ACE_Framework_Repository
class ACE_Object_Manager

Detailed Description

This class is a singleton and serves as a factory and repository for instances of ACE_DLL_Handle.

This class is a singleton whose lifetime is managed by the ACE_Framework_Repository. Although it is normally meant to be used directly only by ACE_DLL, applications can call the unload_policy() methods in order get/set the the dll unload policy. Unload policies include per_process/per-dll and eager/lazy. Dlls can export set their own policy by using the ACE_DLL_UNLOAD_POLICY macro found in config-all.h. If a dll choses to set an unload policy, it will be used when the per-dll policy (the default) is in effect. If the per-dll policy is in effect and a dll has not chosen to set a policy, the current per-process policy will be used.

The following policy macros are provided in config-all.h:

ACE_DLL_UNLOAD_POLICY_PER_PROCESS - Per-process policy that unloads dlls eagerly.

ACE_DLL_UNLOAD_POLICY_PER_DLL - Apply policy on a per-dll basis. If the dll doesn't use one of the macros below, the current per-process policy will be used.

ACE_DLL_UNLOAD_POLICY_LAZY - Don't unload dll when refcount reaches zero, i.e., wait for either an explicit unload request or program exit.

ACE_DLL_UNLOAD_POLICY_DEFAULT - Default policy allows dlls to control their own destinies, but will unload those that don't make a choice eagerly.

Definition at line 182 of file DLL_Manager.h.


Member Enumeration Documentation

anonymous enum
Enumerator:
DEFAULT_SIZE 

Definition at line 188 of file DLL_Manager.h.


Constructor & Destructor Documentation

ACE_DLL_Manager::ACE_DLL_Manager ( int  size = ACE_DLL_Manager::DEFAULT_SIZE  )  [protected]

Default constructor.

Definition at line 530 of file DLL_Manager.cpp.

  : handle_vector_ (0),
    current_size_ (0),
    total_size_ (0),
    unload_policy_ (ACE_DLL_UNLOAD_POLICY_PER_DLL)
{
  ACE_TRACE ("ACE_DLL_Manager::ACE_DLL_Manager");

  if (this->open (size) != 0 && ACE::debug ())
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("ACE (%P|%t) DLL_Manager ctor failed to allocate ")
                ACE_TEXT ("handle_vector_.\n")));
}

ACE_DLL_Manager::~ACE_DLL_Manager ( void   )  [protected]

Destructor.

Definition at line 544 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::~ACE_DLL_Manager");

  if (this->close () != 0 && ACE::debug ())
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("ACE (%P|%t) DLL_Manager dtor failed to close ")
                ACE_TEXT ("properly.\n")));
}

ACE_DLL_Manager::ACE_DLL_Manager ( const ACE_DLL_Manager  )  [private]

Disallow copying and assignment since we don't handle these.


Member Function Documentation

int ACE_DLL_Manager::close ( void   )  [protected]

Close all open dlls and deallocate memory.

Definition at line 678 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::close");

  int force_close = 1;

  if (this->handle_vector_ != 0)
    {
      // Delete components in reverse order.
      for (int i = this->current_size_ - 1; i >= 0; i--)
        {
          if (this->handle_vector_[i])
            {
              ACE_DLL_Handle *s =
                const_cast<ACE_DLL_Handle *> (this->handle_vector_[i]);
              this->handle_vector_[i] = 0;
              this->unload_dll (s, force_close);
              delete s;
            }
        }

      delete [] this->handle_vector_;
      this->handle_vector_ = 0;
      this->current_size_ = 0;
    }
  return 0;
}

int ACE_DLL_Manager::close_dll ( const ACE_TCHAR dll_name  ) 

Close the underlying dll. Decrements the refcount.

Definition at line 608 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::close_dll");
  ACE_DLL_Handle *handle = 0;

  {
    ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
    handle = this->find_dll (dll_name);
  }

  if (handle)
    {
      return this->unload_dll (handle, 0);
    }

  return -1;
}

void ACE_DLL_Manager::close_singleton ( void   )  [static, private]

Close the singleton instance.

Definition at line 519 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::close_singleton");

  ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
                     *ACE_Static_Object_Lock::instance ()));

  delete ACE_DLL_Manager::instance_;
  ACE_DLL_Manager::instance_ = 0;
}

ACE_DLL_Handle * ACE_DLL_Manager::find_dll ( const ACE_TCHAR dll_name  )  const [protected]

Find dll in handle_vector_.

Definition at line 707 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::find_dll");

  for (int i = 0; i < this->current_size_; i++)
    if (this->handle_vector_[i] &&
        ACE_OS::strcmp (this->handle_vector_[i]->dll_name (), dll_name) == 0)
      {
        return this->handle_vector_[i];
      }

  return 0;
}

ACE_DLL_Manager * ACE_DLL_Manager::instance ( int  size = ACE_DLL_Manager::DEFAULT_SIZE  )  [static]

Return a unique instance.

Definition at line 498 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::instance");

  if (ACE_DLL_Manager::instance_ == 0)
    {
      // Perform Double-Checked Locking Optimization.
      ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
                                *ACE_Static_Object_Lock::instance (), 0));
      if (ACE_DLL_Manager::instance_ == 0)
        {
          ACE_NEW_RETURN (ACE_DLL_Manager::instance_,
                          ACE_DLL_Manager (size),
                          0);
        }
    }

  return ACE_DLL_Manager::instance_;
}

int ACE_DLL_Manager::open ( int  size  )  [protected]

Allocate handle_vector_.

Definition at line 662 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::open");

  ACE_DLL_Handle **temp = 0;

  ACE_NEW_RETURN (temp,
                  ACE_DLL_Handle *[size],
                  -1);

  this->handle_vector_ = temp;
  this->total_size_ = size;
  return 0;
}

ACE_DLL_Handle * ACE_DLL_Manager::open_dll ( const ACE_TCHAR dll_name,
int  openmode,
ACE_SHLIB_HANDLE  handle 
)

Factory for ACE_DLL_Handle objects. If one already exits, its refcount is incremented.

Definition at line 555 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::open_dll");

  ACE_DLL_Handle *temp_handle = 0;
  ACE_DLL_Handle *dll_handle = 0;
  {
    ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
    dll_handle = this->find_dll (dll_name);
    if (!dll_handle)
      {
        if (this->current_size_ < this->total_size_)
          {
            ACE_NEW_RETURN (temp_handle,
                            ACE_DLL_Handle,
                            0);

            dll_handle = temp_handle;
          }
      }
  }

  if (dll_handle)
    {
      if (dll_handle->open (dll_name, open_mode, handle) != 0)
        {
          // Error while opening dll. Free temp handle
          if (ACE::debug ())
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT ("ACE (%P|%t) DLL_Manager::open_dll: Could not ")
                        ACE_TEXT ("open dll %s.\n"),
                        dll_name));

          delete temp_handle;
          return 0;
        }

      // Add the handle to the vector only if the dll is successfully
      // opened.
      if (temp_handle != 0)
        {
          ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, 0));
          this->handle_vector_[this->current_size_] = dll_handle;
          ++this->current_size_;
        }
    }

  return dll_handle;
}

void ACE_DLL_Manager::operator= ( const ACE_DLL_Manager  )  [private]
int ACE_DLL_Manager::unload_dll ( ACE_DLL_Handle dll_handle,
int  force_unload = 0 
) [protected]

Applies strategy for unloading dll.

Definition at line 722 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::unload_dll");

  if (dll_handle)
    {
      int unload = force_unload;
      if (unload == 0)
        {
          // apply strategy
          if (ACE_BIT_DISABLED (this->unload_policy_,
                                ACE_DLL_UNLOAD_POLICY_PER_DLL))
            {
              unload = ACE_BIT_DISABLED (this->unload_policy_,
                                         ACE_DLL_UNLOAD_POLICY_LAZY);
            }
          else
            {
              // Declare the type of the symbol:
              typedef int (*dll_unload_policy)(void);

              void * const unload_policy_ptr =
                dll_handle->symbol (ACE_TEXT ("_get_dll_unload_policy"), 1);
#if defined (ACE_OPENVMS) && (!defined (__INITIAL_POINTER_SIZE) || (__INITIAL_POINTER_SIZE < 64))
              int const temp_p =
                reinterpret_cast<int> (unload_policy_ptr);
#else
              intptr_t const temp_p =
                reinterpret_cast<intptr_t> (unload_policy_ptr);
#endif

              dll_unload_policy const the_policy =
                reinterpret_cast<dll_unload_policy> (temp_p);

              if (the_policy != 0)
                unload = ACE_BIT_DISABLED (the_policy (),
                                           ACE_DLL_UNLOAD_POLICY_LAZY);
              else
                unload = ACE_BIT_DISABLED (this->unload_policy_,
                                           ACE_DLL_UNLOAD_POLICY_LAZY);
            }
        }

      if (dll_handle->close (unload) != 0)
        {
          if (ACE::debug ())
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT ("ACE (%P|%t) DLL_Manager::unload error.\n")));

          return -1;
        }
    }
  else
    {
      if (ACE::debug ())
        ACE_ERROR ((LM_ERROR,
                    ACE_TEXT ("ACE (%P|%t) DLL_Manager::unload_dll called with ")
                    ACE_TEXT ("null pointer.\n")));

      return -1;
    }

  return 0;
}

void ACE_DLL_Manager::unload_policy ( u_long  unload_policy  ) 

Set the per-process UNLOAD_POLICY. If the policy is changed from LAZY to EAGER, then it will also unload any dlls with zero refcounts.

Definition at line 634 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::unload_policy");
  ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, this->lock_));

  u_long old_policy = this->unload_policy_;
  this->unload_policy_ = unload_policy;

  // If going from LAZY to EAGER or from PER_DLL to PER_PROCESS|EAGER,
  // call close(1) on all the ACE_DLL_Handle objects with refcount == 0
  // which will force those that are still loaded to be unloaded.
  if (this->handle_vector_)
    if (( ACE_BIT_ENABLED (old_policy, ACE_DLL_UNLOAD_POLICY_LAZY) &&
          ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_LAZY) ) ||
        ( ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_LAZY) &&
          ACE_BIT_ENABLED (old_policy, ACE_DLL_UNLOAD_POLICY_PER_DLL) &&
          ACE_BIT_DISABLED (this->unload_policy_, ACE_DLL_UNLOAD_POLICY_PER_DLL) ))
      {
        for (int i = this->current_size_ - 1; i >= 0; i--)
          {
            if (this->handle_vector_[i] &&
                this->handle_vector_[i]->refcount () == 0)
              this->handle_vector_[i]->close (1);
          }
      }
}

u_long ACE_DLL_Manager::unload_policy ( void   )  const

Returns the current per-process UNLOAD_POLICY.

Definition at line 627 of file DLL_Manager.cpp.

{
  ACE_TRACE ("ACE_DLL_Manager::unload_policy");
  return this->unload_policy_;
}


Friends And Related Function Documentation

friend class ACE_Framework_Repository [friend]

Definition at line 185 of file DLL_Manager.h.

friend class ACE_Object_Manager [friend]

Definition at line 186 of file DLL_Manager.h.


Member Data Documentation

Current number of handles.

Definition at line 248 of file DLL_Manager.h.

Vector containing all loaded handle objects.

Definition at line 245 of file DLL_Manager.h.

Pointer to a process-wide ACE_DLL_Manager.

Definition at line 257 of file DLL_Manager.h.

Maximum number of handles.

Definition at line 251 of file DLL_Manager.h.

Unload strategy.

Definition at line 254 of file DLL_Manager.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines