int
ACE_Service_Repository::relocate_i (size_t begin,
                                    size_t end,
                                    const ACE_DLL& adll)
{
    ACE_SHLIB_HANDLE new_handle = adll.get_handle (0);

    for (size_t i = begin; i < end; i++)
    {
        ACE_Service_Type *type =
            const_cast<ACE_Service_Type *> (this->service_vector_[i]);

        ACE_SHLIB_HANDLE old_handle = (type == 0) ? ACE_SHLIB_INVALID_HANDLE
                                      : type->dll ().get_handle (0);

#ifndef ACE_NLOGGING
        if (ACE::debug ())
        {
            if (type == 0)
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)")
                            ACE_TEXT (": skipping empty slot\n"),
                            this,
                            i,
                            this->total_size_));
            else
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)")
                            ACE_TEXT (": trying name=%s, handle: %d -> %d\n"),
                            this,
                            i,
                            this->total_size_,
                            type->name (),
                            old_handle,
                            new_handle));
        }
#endif

        if (type != 0  // skip any gaps
                && old_handle == ACE_SHLIB_INVALID_HANDLE
                && new_handle != old_handle)
        {
#ifndef ACE_NLOGGING
            if (ACE::debug ())
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("ACE (%P|%t) SR::relocate_i - repo=%@ [%d] (size=%d)")
                            ACE_TEXT (": relocating name=%s, handle: %d -> %d\n"),
                            this,
                            i,
                            this->total_size_,
                            type->name (),
                            old_handle,
                            new_handle));
#endif
            type->dll (adll); // ups the refcount on adll
        }
    }

    return 0;
}
int
ACE_Service_Repository::close (void)
{
    ACE_TRACE ("ACE_Service_Repository::close");
    ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));

    if (this->service_vector_ == 0)
        return 0;

#ifndef ACE_NLOGGING
    if (ACE::debug ())
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("(%P|%t) SR::close - repo=%@, size=%d\n"),
                    this,
                    this->current_size_));
#endif

    // Do not use the prefix decrement operator since the index is
    // unsigned and may wrap around the 0.
    for (size_t i = this->current_size_; i-- != 0;)
    {
        // Delete services in reverse order.
        ACE_Service_Type *s =
            const_cast<ACE_Service_Type *> (this->service_vector_[i]);

#ifndef ACE_NLOGGING
        if (ACE::debug ())
        {
            if (s == 0)
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("(%P|%t) SR::close - repo=%@ [%d] -> 0\n"),
                            this,
                            i));
            else
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("(%P|%t) SR::close - repo=%@ [%d], name=%s, object=%@\n"),
                            this,
                            i,
                            s->name (),
                            s));
        }
#endif
        --this->current_size_;
        delete s;
    }

    delete [] this->service_vector_;
    this->service_vector_ = 0;
    this->current_size_ = 0;

    return 0;
}
int
ACE_Service_Repository::fini (void)
{
    ACE_TRACE ("ACE_Service_Repository::fini");
    ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));

    if (this->service_vector_ == 0)
        return 0;

    int retval = 0;

    // Do not be tempted to use the prefix decrement operator.  Use
    // postfix decrement operator since the index is unsigned and may
    // wrap around the 0
    for (size_t i = this->current_size_; i-- != 0;)
    {
        // <fini> the services in reverse order.
        ACE_Service_Type *s =
            const_cast<ACE_Service_Type *> (this->service_vector_[i]);

#ifndef ACE_NLOGGING
        if (ACE::debug ())
        {
            if (s != 0)
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d), ")
                            ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
                            this,
                            i,
                            this->total_size_,
                            s->name(),
                            s->type (),
                            (s->type () != 0) ? s->type ()->object () : 0,
                            s->active ()));
            else
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] (%d) -> 0\n"),
                            this,
                            i,
                            this->total_size_));
        }
#endif

        // Collect any errors.
        if (s != 0)
            retval += s->fini ();
    }

    return (retval == 0) ? 0 : -1;
}
Beispiel #4
0
int
ACE_Service_Gestalt::initialize (const ACE_Service_Type_Factory *stf,
                                 const ACE_TCHAR *parameters)
{
  ACE_TRACE ("ACE_Service_Gestalt::initialize");

#ifndef ACE_NLOGGING
  if (ACE::debug ())
    ACELIB_DEBUG ((LM_DEBUG,
                ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@, name=%s")
                ACE_TEXT (" - looking up in the repo\n"),
                this->repo_,
                stf->name ()));
#endif

  ACE_Service_Type *srp = 0;
  int const retv = this->repo_->find (stf->name (),
                                      (const ACE_Service_Type **) &srp);

  // If there is an active service already, remove it first
  // before it can be re-installed.
  if (retv >= 0)
    {
#ifndef ACE_NLOGGING
      if (ACE::debug ())
        ACELIB_DEBUG ((LM_WARNING,
                    ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@,")
                    ACE_TEXT (" name=%s - removing a pre-existing namesake.\n"),
                    this->repo_,
                    stf->name ()));
#endif
      this->repo_->remove (stf->name ());
    }

  // If there is an inactive service by that name it may have been
  // either inactivated, or just a forward declaration for a service,
  // that is in the process of being initialized. If it is the latter,
  // then we have detected an attempt to initialize the same dynamic
  // service while still processing previous attempt. This can lock up
  // the process, because the ACE_DLL_Manager::open () is not
  // re-entrant - it uses a Singleton lock to serialize concurent
  // invocations. This use case must be handled here, because if the
  // DLL_Manager was re-entrant we would have entered an infinite
  // recursion here.
  if (retv == -2 && srp->type () == 0)
    ACELIB_ERROR_RETURN ((LM_WARNING,
                       ACE_TEXT ("ACE (%P|%t) SG::initialize - repo=%@,")
                       ACE_TEXT (" name=%s - forward-declared; ")
                       ACE_TEXT (" recursive initialization requests are")
                       ACE_TEXT (" ignored.\n"),
                       this->repo_,
                       stf->name ()),
                      -1);

  // Reserve a spot for the dynamic service by inserting an incomplete
  // service declaration, i.e. one that can not produce a service
  // object if asked (a forward declaration).  This declaration
  // ensures maintaining the proper partial ordering of the services
  // with respect to their finalization. For example, dependent static
  // services must be registered *after* the dynamic service that
  // loads them, so that their finalization is complete *before*
  // finalizing the dynamic service.
  ACE_Service_Type_Dynamic_Guard dummy (*this->repo_,
                                        stf->name ());

  // make_service_type() is doing the dynamic loading and also runs
  // any static initializers
  ACE_Auto_Ptr<ACE_Service_Type> tmp (stf->make_service_type (this));

  if (tmp.get () != 0 &&
      this->initialize_i (tmp.get (), parameters) == 0)
    {
      // All good. Tthe ACE_Service_Type instance is now owned by the
      // repository and we should make sure it is not destroyed upon
      // exit from this method.
      tmp.release ();
      return 0;
    }

  return -1;
}
int
ACE_Service_Repository::fini (void)
{
  ACE_TRACE ("ACE_Service_Repository::fini");
  ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));

  int retval = 0;
  // Do not be tempted to use the prefix decrement operator.  Use
  // postfix decrement operator since the index is unsigned and may
  // wrap around the 0
  //
  // debug output for empty service entries
#ifndef ACE_NLOGGING
  if (ACE::debug ())
  {
    for (size_t i = this->service_array_.size (); i-- != 0;)
    {
      ACE_Service_Type *s =
        const_cast<ACE_Service_Type *> (this->service_array_[i]);
      if (s == 0)
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d] -> 0\n"),
                    this,
                    i));
    }
  }
#endif
  //
  // Remove all the Service_Object and Stream instances
  //
  for (size_t i = this->service_array_.size (); i-- != 0;)
  {
    // <fini> the services in reverse order.
    ACE_Service_Type *s =
      const_cast<ACE_Service_Type *> (this->service_array_[i]);

    if (s != 0 &&
        s->type () != 0 &&
        (s->type ()->service_type () != ACE_Service_Type::MODULE))
    {
#ifndef ACE_NLOGGING
      if (ACE::debug ())
      {
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ")
                    ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
                    this,
                    i,
                    s->name (),
                    s->type (),
                    (s->type () != 0) ? s->type ()->object () : 0,
                    s->active ()));
      }
#endif

      // Collect any errors.
      retval += s->fini ();
    }
  }
  //
  // Remove all the Module instances
  //
  for (size_t i = this->service_array_.size (); i-- != 0;)
  {
    // <fini> the services in reverse order.
    ACE_Service_Type *s =
      const_cast<ACE_Service_Type *> (this->service_array_[i]);

    if (s != 0 &&
        s->type () != 0 &&
        (s->type ()->service_type () == ACE_Service_Type::MODULE))
    {
#ifndef ACE_NLOGGING
      if (ACE::debug ())
      {
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("ACE (%P|%t) SR::fini, repo=%@ [%d], ")
                    ACE_TEXT ("name=%s, type=%@, object=%@, active=%d\n"),
                    this,
                    i,
                    s->name (),
                    s->type (),
                    (s->type () != 0) ? s->type ()->object () : 0,
                    s->active ()));
      }
#endif
      // Collect any errors.
      retval += s->fini ();
    }
  }
  return (retval == 0) ? 0 : -1;
}