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

ACE_Stream< ACE_SYNCH_DECL > Class Template Reference

This class is the primary abstraction for the ASX framework. It is moduled after System V Stream. More...

#include <Stream.h>

Collaboration diagram for ACE_Stream< ACE_SYNCH_DECL >:
Collaboration graph
[legend]

List of all members.

Public Types

enum  { M_DELETE = 3 }

Public Member Functions

 ACE_Stream (void *arg=0, ACE_Module< ACE_SYNCH_USE > *head=0, ACE_Module< ACE_SYNCH_USE > *tail=0)
virtual int open (void *arg, ACE_Module< ACE_SYNCH_USE > *head=0, ACE_Module< ACE_SYNCH_USE > *tail=0)
virtual int close (int flags=M_DELETE)
 Close down the stream and release all the resources.
virtual ~ACE_Stream (void)
 Close down the stream and release all the resources.
virtual int push (ACE_Module< ACE_SYNCH_USE > *mod)
virtual int pop (int flags=M_DELETE)
 Remove the mod right below the Stream head and close it down.
virtual int top (ACE_Module< ACE_SYNCH_USE > *&mod)
virtual int insert (const ACE_TCHAR *prev_name, ACE_Module< ACE_SYNCH_USE > *mod)
 Insert a new module mod below the named module prev_name.
virtual int replace (const ACE_TCHAR *replace_name, ACE_Module< ACE_SYNCH_USE > *mod, int flags=M_DELETE)
 Replace the named module replace_name with a new module mod.
virtual int remove (const ACE_TCHAR *mod, int flags=M_DELETE)
virtual ACE_Module
< ACE_SYNCH_USE > * 
head (void)
 Return current stream head.
virtual ACE_Module
< ACE_SYNCH_USE > * 
tail (void)
 Return current stream tail.
virtual ACE_Module
< ACE_SYNCH_USE > * 
find (const ACE_TCHAR *mod)
 Find a particular ACE_Module.
virtual int link (ACE_Stream< ACE_SYNCH_USE > &)
 Create a pipe between two Streams.
virtual int unlink (void)
 Remove a pipe formed between two Streams.
virtual int put (ACE_Message_Block *mb, ACE_Time_Value *timeout=0)
virtual int get (ACE_Message_Block *&mb, ACE_Time_Value *timeout=0)
virtual int control (ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds cmd, void *args)
 Send control message down the stream.
virtual int wait (void)
 Synchronize with the final close of the stream.
virtual void dump (void) const
 Dump the state of an object.

Public Attributes

 ACE_ALLOC_HOOK_DECLARE
 Declare the dynamic allocation hooks.

Private Member Functions

int unlink_i (void)
int link_i (ACE_Stream< ACE_SYNCH_USE > &)
int push_module (ACE_Module< ACE_SYNCH_USE > *, ACE_Module< ACE_SYNCH_USE > *=0, ACE_Module< ACE_SYNCH_USE > *=0)
 Must a new module onto the Stream.

Private Attributes

ACE_Module< ACE_SYNCH_USE > * stream_head_
 Pointer to the head of the stream.
ACE_Module< ACE_SYNCH_USE > * stream_tail_
 Pointer to the tail of the stream.
ACE_Stream< ACE_SYNCH_USE > * linked_us_
 Pointer to an adjoining linked stream.
ACE_SYNCH_MUTEX_T lock_
 Protect the stream against race conditions.
ACE_SYNCH_CONDITION_T final_close_
 Use to tell all threads waiting on the close that we are done.

Friends

class ACE_Stream_Iterator< ACE_SYNCH_USE >

Detailed Description

template<ACE_SYNCH_DECL>
class ACE_Stream< ACE_SYNCH_DECL >

This class is the primary abstraction for the ASX framework. It is moduled after System V Stream.

A Stream consists of a stack of ACE_Modules, each of which contains two ACE_Tasks. Even though the methods in this class are virtual, this class isn't really intended for subclassing unless you know what you are doing. In particular, the ACE_Stream destructor calls <close>, which won't be overridden properly unless you call it in a subclass destructor.

Definition at line 49 of file Stream.h.


Member Enumeration Documentation

template<ACE_SYNCH_DECL >
anonymous enum
Enumerator:
M_DELETE 

Indicates that close() deletes the Tasks. Don't change this value without updating the same enum in class ACE_Module...

Definition at line 54 of file Stream.h.

  {
    /// Indicates that @c close() deletes the Tasks.  Don't change this
    /// value without updating the same enum in class ACE_Module...
    M_DELETE = 3
  };


Constructor & Destructor Documentation

template<ACE_SYNCH_DECL >
ACE_Stream< ACE_SYNCH_DECL >::ACE_Stream ( void *  arg = 0,
ACE_Module< ACE_SYNCH_USE > *  head = 0,
ACE_Module< ACE_SYNCH_USE > *  tail = 0 
)

Create a Stream consisting of head and tail as the Stream head and Stream tail, respectively. If these are 0 then the ACE_Stream_Head and ACE_Stream_Tail are used, respectively. arg is the value past in to the <open> methods of the tasks.

Definition at line 602 of file Stream.cpp.

  : linked_us_ (0),
    final_close_ (lock_)
{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::ACE_Stream");
  if (this->open (a, head, tail) == -1)
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("ACE_Stream<ACE_SYNCH_USE>::open (%s, %s)\n"),
               head->name (), tail->name ()));
}

template<ACE_SYNCH_DECL >
ACE_Stream< ACE_SYNCH_DECL >::~ACE_Stream ( void   )  [virtual]

Close down the stream and release all the resources.

Definition at line 616 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::~ACE_Stream");

  if (this->stream_head_ != 0)
    this->close ();
}


Member Function Documentation

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::close ( int  flags = M_DELETE  )  [virtual]

Close down the stream and release all the resources.

Definition at line 405 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::close");
  ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->lock_, -1);

  if (this->stream_head_ != 0
      && this->stream_tail_ != 0)
    {
      // Don't bother checking return value here.
      this->unlink_i ();

      int result = 0;

      // Remove and cleanup all the intermediate modules.

      while (this->stream_head_->next () != this->stream_tail_)
        if (this->pop (flags) == -1)
          result = -1;

      // Clean up the head and tail of the stream.
      if (this->stream_head_->close (flags) == -1)
        result = -1;
      if (this->stream_tail_->close (flags) == -1)
        result = -1;

      // Cleanup the memory.
      delete this->stream_head_;
      delete this->stream_tail_;

      this->stream_head_ = 0;
      this->stream_tail_ = 0;

      // Tell all threads waiting on the close that we are done.
      this->final_close_.broadcast ();
      return result;
    }
  return 0;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::control ( ACE_IO_Cntl_Msg::ACE_IO_Cntl_Cmds  cmd,
void *  args 
) [virtual]

Send control message down the stream.

Definition at line 445 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::control");
  ACE_IO_Cntl_Msg ioc (cmd);

  ACE_Message_Block *db;

  // Try to create a data block that contains the user-supplied data.
  ACE_NEW_RETURN (db,
                  ACE_Message_Block (sizeof (int),
                                     ACE_Message_Block::MB_IOCTL,
                                     0,
                                     (char *) a),
                  -1);
  // Try to create a control block <cb> that contains the control
  // field and a pointer to the data block <db> in <cb>'s continuation
  // field.
  ACE_Message_Block *cb = 0;

  ACE_NEW_RETURN (cb,
                  ACE_Message_Block (sizeof ioc,
                                     ACE_Message_Block::MB_IOCTL,
                                     db,
                                     (char *) &ioc),
                  -1);
  // @@ Michael: The old semantic assumed that cb returns == 0
  //             if no memory was available. We will now return immediately
  //             without release (errno is set to ENOMEM by the macro).

  // If we can't allocate <cb> then we need to delete db and return
  // -1.
  if (cb == 0)
    {
      db->release ();
      errno = ENOMEM;
      return -1;
    }

  int result;

  if (this->stream_head_->writer ()->put (cb) == -1)
    result = -1;
  else if (this->stream_head_->reader ()->getq (cb) == -1)
    result = -1;
  else
    result = ((ACE_IO_Cntl_Msg *) cb->rd_ptr ())->rval ();

  // This will also release db if it's reference count == 0.
  cb->release ();

  return result;
}

template<ACE_SYNCH_DECL >
void ACE_Stream< ACE_SYNCH_DECL >::dump ( void   )  const [virtual]

Dump the state of an object.

Definition at line 29 of file Stream.cpp.

{
#if defined (ACE_HAS_DUMP)
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::dump");
  ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("-------- module links --------\n")));

  for (ACE_Module<ACE_SYNCH_USE> *mp = this->stream_head_;
       ;
       mp = mp->next ())
    {
      ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("module name = %s\n"), mp->name ()));
      if (mp == this->stream_tail_)
        break;
    }

  ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("-------- writer links --------\n")));

  ACE_Task<ACE_SYNCH_USE> *tp;

  for (tp = this->stream_head_->writer ();
       ;
       tp = tp->next ())
    {
      ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("writer queue name = %s\n"), tp->name ()));
      tp->dump ();
      ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("-------\n")));
      if (tp == this->stream_tail_->writer ()
          || (this->linked_us_
              && tp == this->linked_us_->stream_head_->reader ()))
        break;
    }

  ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("-------- reader links --------\n")));
  for (tp = this->stream_tail_->reader (); ; tp = tp->next ())
    {
      ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("reader queue name = %s\n"), tp->name ()));
      tp->dump ();
      ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("-------\n")));
      if (tp == this->stream_head_->reader ()
          || (this->linked_us_
              && tp == this->linked_us_->stream_head_->writer ()))
        break;
    }
#endif /* ACE_HAS_DUMP */
}

template<ACE_SYNCH_DECL >
ACE_Module< ACE_SYNCH_USE > * ACE_Stream< ACE_SYNCH_DECL >::find ( const ACE_TCHAR mod  )  [virtual]

Find a particular ACE_Module.

Definition at line 282 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::find");
  for (ACE_Module<ACE_SYNCH_USE> *mod = this->stream_head_;
       mod != 0;
       mod = mod->next ())
    if (ACE_OS::strcmp (mod->name (), name) == 0)
        return mod;

  return 0;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::get ( ACE_Message_Block *&  mb,
ACE_Time_Value timeout = 0 
) [virtual]

Read the message mb that is stored in the stream head. Wait for upto timeout amount of absolute time for the operation to complete (or block forever if timeout == 0).

Definition at line 95 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::get");
  return this->stream_head_->reader ()->getq (mb, tv);
}

template<ACE_SYNCH_DECL >
ACE_Module< ACE_SYNCH_USE > * ACE_Stream< ACE_SYNCH_DECL >::head ( void   )  [virtual]

Return current stream head.

Definition at line 8 of file Stream.inl.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::head");
  return this->stream_head_;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::insert ( const ACE_TCHAR prev_name,
ACE_Module< ACE_SYNCH_USE > *  mod 
) [virtual]

Insert a new module mod below the named module prev_name.

Definition at line 118 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::insert");

  for (ACE_Module<ACE_SYNCH_USE> *prev_mod = this->stream_head_;
       prev_mod != 0;
       prev_mod = prev_mod->next ())
    if (ACE_OS::strcmp (prev_mod->name (), prev_name) == 0)
      {
        ACE_Module<ACE_SYNCH_USE> *next_mod = prev_mod->next ();

        // We can't insert a module below <stream_tail_>.
        if (next_mod == 0)
          return -1;

        mod->link (next_mod);
        prev_mod->link (mod);

        if (mod->reader ()->open (mod->arg ()) == -1)
          return -1;

        if (mod->writer ()->open (mod->arg ()) == -1)
          return -1;

        return 0;
      }

  return -1;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::link ( ACE_Stream< ACE_SYNCH_USE > &  us  )  [virtual]

Create a pipe between two Streams.

Definition at line 537 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::link");

  ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->lock_, -1);

  return this->link_i (us);
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::link_i ( ACE_Stream< ACE_SYNCH_USE > &  us  )  [private]

Actually perform the linking of two Streams (must be called with locks held).

Definition at line 505 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::link_i");
  this->linked_us_ = &us;
  // Make sure the other side is also linked to us!
  us.linked_us_ = this;

  ACE_Module<ACE_SYNCH_USE> *my_tail = this->stream_head_;

  if (my_tail == 0)
    return -1;

  // Locate the module just above our Stream tail.
  while (my_tail->next () != this->stream_tail_)
    my_tail = my_tail->next ();

  ACE_Module<ACE_SYNCH_USE> *other_tail = us.stream_head_;

  if (other_tail == 0)
    return -1;

  // Locate the module just above the other Stream's tail.
  while (other_tail->next () != us.stream_tail_)
    other_tail = other_tail->next ();

  // Reattach the pointers so that the two streams are linked!
  my_tail->writer ()->next (other_tail->reader ());
  other_tail->writer ()->next (my_tail->reader ());
  return 0;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::open ( void *  arg,
ACE_Module< ACE_SYNCH_USE > *  head = 0,
ACE_Module< ACE_SYNCH_USE > *  tail = 0 
) [virtual]

Create a Stream consisting of head and tail as the Stream head and Stream tail, respectively. If these are 0 then the ACE_Stream_Head and ACE_Stream_Tail are used, respectively. arg is the value past in to the open() methods of the tasks.

Definition at line 335 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::open");
  ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->lock_, -1);

  ACE_Task<ACE_SYNCH_USE> *h1 = 0, *h2 = 0;
  ACE_Task<ACE_SYNCH_USE> *t1 = 0, *t2 = 0;

  if (head == 0)
    {
      ACE_NEW_RETURN (h1,
                      ACE_Stream_Head<ACE_SYNCH_USE>,
                      -1);
      ACE_NEW_RETURN (h2,
                      ACE_Stream_Head<ACE_SYNCH_USE>,
                      -1);
      ACE_NEW_RETURN (head,
                      ACE_Module<ACE_SYNCH_USE> (ACE_TEXT ("ACE_Stream_Head"),
                                                 h1, h2,
                                                 a,
                                                 M_DELETE),
                      -1);
    }

  if (tail == 0)
    {
      ACE_NEW_RETURN (t1,
                      ACE_Stream_Tail<ACE_SYNCH_USE>,
                      -1);
      ACE_NEW_RETURN (t2,
                      ACE_Stream_Tail<ACE_SYNCH_USE>,
                      -1);
      ACE_NEW_RETURN (tail,
                      ACE_Module<ACE_SYNCH_USE> (ACE_TEXT ("ACE_Stream_Tail"),
                                                 t1, t2,
                                                 a,
                                                 M_DELETE),
                      -1);
    }

  // Make sure *all* the allocation succeeded!
  if ((head == 0 && (h1 == 0 || h2 == 0))
      || (tail == 0 && (t1 == 0 || t2 == 0)))
    {
      delete h1;
      delete h2;
      delete t1;
      delete t2;
      delete head;
      delete tail;
      errno = ENOMEM;
      return -1;
    }

  this->stream_head_ = head;
  this->stream_tail_ = tail;

  if (this->push_module (this->stream_tail_) == -1)
    return -1;
  else if (this->push_module (this->stream_head_,
                              this->stream_tail_,
                              this->stream_head_) == -1)
    return -1;

  return 0;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::pop ( int  flags = M_DELETE  )  [virtual]

Remove the mod right below the Stream head and close it down.

are invoked to cleanup the tasks.

Definition at line 205 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::pop");
  if (this->stream_head_->next () == this->stream_tail_)
    return -1;
  else
    {
      // Skip over the ACE_Stream head.
      ACE_Module<ACE_SYNCH_USE> *top_mod = this->stream_head_->next ();
      ACE_Module<ACE_SYNCH_USE> *new_top = top_mod->next ();

      this->stream_head_->next (new_top);

      // Close the top ACE_Module.

      top_mod->close (flags);

      // Don't delete the Module unless the flags request this.
      if (flags != ACE_Module<ACE_SYNCH_USE>::M_DELETE_NONE)
        delete top_mod;

      this->stream_head_->writer ()->next (new_top->writer ());
      new_top->reader ()->next (this->stream_head_->reader ());
      return 0;
    }
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::push ( ACE_Module< ACE_SYNCH_USE > *  mod  )  [virtual]

Add a new module mod right below the Stream head. The open() hook methods of the ACE_Tasks in this ACE_Module are invoked to initialize the tasks.

Definition at line 76 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::push");
  if (this->push_module  (new_top,
                          this->stream_head_->next (),
                          this->stream_head_) == -1)
    return -1;
  else
    return 0;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::push_module ( ACE_Module< ACE_SYNCH_USE > *  new_top,
ACE_Module< ACE_SYNCH_USE > *  current_top = 0,
ACE_Module< ACE_SYNCH_USE > *  head = 0 
) [private]

Must a new module onto the Stream.

Definition at line 297 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::push_module");
  ACE_Task<ACE_SYNCH_USE> *nt_reader = new_top->reader ();
  ACE_Task<ACE_SYNCH_USE> *nt_writer = new_top->writer ();
  ACE_Task<ACE_SYNCH_USE> *ct_reader = 0;
  ACE_Task<ACE_SYNCH_USE> *ct_writer = 0;

  if (current_top)
    {
      ct_reader = current_top->reader ();
      ct_writer = current_top->writer ();
      ct_reader->next (nt_reader);
    }

  nt_writer->next (ct_writer);

  if (head)
    {
      if (head != new_top)
        head->link (new_top);
    }
  else
    nt_reader->next (0);

  new_top->next (current_top);

  if (nt_reader->open (new_top->arg ()) == -1)
    return -1;

  if (nt_writer->open (new_top->arg ()) == -1)
    return -1;
  return 0;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::put ( ACE_Message_Block mb,
ACE_Time_Value timeout = 0 
) [virtual]

Send the message mb down the stream, starting at the Module below the Stream head. Wait for upto timeout amount of absolute time for the operation to complete (or block forever if timeout == 0).

Definition at line 88 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::put");
  return this->stream_head_->writer ()->put (mb, tv);
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::remove ( const ACE_TCHAR mod,
int  flags = M_DELETE 
) [virtual]

Remove the named module mod from the stream. This bypasses the strict LIFO ordering of push and pop.

Definition at line 236 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::remove");
  ACE_Module<ACE_SYNCH_USE> *prev = 0;

  for (ACE_Module<ACE_SYNCH_USE> *mod = this->stream_head_;
       mod != 0;
       mod = mod->next ())
  {
#ifndef ACE_NLOGGING
    if (ACE::debug ())
    {
      ACE_DEBUG ((LM_DEBUG,
        ACE_TEXT ("ACE_Stream::remove comparing existing module :%s: with :%s:\n"),
        mod->name (),
        name));
    }
#endif

    if (ACE_OS::strcmp (mod->name (), name) == 0)
      {
        if (prev == 0) // Deleting ACE_Stream Head
          this->stream_head_->link (mod->next ());
        else
          prev->link (mod->next ());

        // Don't delete the Module unless the flags request this.
        if (flags != ACE_Module<ACE_SYNCH_USE>::M_DELETE_NONE)
          {
            // Close down the module and release the memory.
            mod->close (flags);
            delete mod;
          }

        return 0;
      }
    else
      prev = mod;
  }

  ACE_DEBUG ((LM_WARNING,  ACE_TEXT ("ACE_Stream::remove failed to find module with name %s to remove\n"),name));
  return -1;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::replace ( const ACE_TCHAR replace_name,
ACE_Module< ACE_SYNCH_USE > *  mod,
int  flags = M_DELETE 
) [virtual]

Replace the named module replace_name with a new module mod.

Definition at line 150 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::replace");
  ACE_Module<ACE_SYNCH_USE> *prev_mod = 0;

  for (ACE_Module<ACE_SYNCH_USE> *rep_mod = this->stream_head_;
       rep_mod != 0;
       rep_mod = rep_mod->next ())
    if (ACE_OS::strcmp (rep_mod->name (), replace_name) == 0)
      {
        ACE_Module<ACE_SYNCH_USE> *next_mod = rep_mod->next ();

        if (next_mod)
          mod->link (next_mod);
        else // In case the <next_mod> is <stream_tail_>.
          {
            mod->writer ()->next (0);
            mod->next (0);
            this->stream_tail_ = mod;
          }

        if (prev_mod)
          prev_mod->link (mod);
        else // In case the <rep_mod> is <stream_head_>.
          {
            mod->reader ()->next (0);
            this->stream_head_ = mod;
          }

        if (mod->reader ()->open (mod->arg ()) == -1)
          return -1;

        if (mod->writer ()->open (mod->arg ()) == -1)
          return -1;

        if (flags != ACE_Module<ACE_SYNCH_USE>::M_DELETE_NONE)
          {
            rep_mod->close (flags);
            delete rep_mod;
          }

        return 0;
      }
    else
      prev_mod = rep_mod;

  return -1;
}

template<ACE_SYNCH_DECL >
ACE_Module< ACE_SYNCH_USE > * ACE_Stream< ACE_SYNCH_DECL >::tail ( void   )  [virtual]

Return current stream tail.

Definition at line 15 of file Stream.inl.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::tail");
  return this->stream_tail_;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::top ( ACE_Module< ACE_SYNCH_USE > *&  mod  )  [virtual]

Return the top module on the stream (right below the stream head).

Definition at line 105 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::top");
  if (this->stream_head_->next () == this->stream_tail_)
    return -1;
  else
    {
      m = this->stream_head_->next ();
      return 0;
    }
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::unlink ( void   )  [virtual]

Remove a pipe formed between two Streams.

Definition at line 594 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::unlink");
  ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->lock_, -1);
  return this->unlink_i ();
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::unlink_i ( void   )  [private]

Actually perform the unlinking of two Streams (must be called with locks held).

Definition at line 549 of file Stream.cpp.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::unlink_i");

  // Only try to unlink if we are in fact still linked!

  if (this->linked_us_ != 0)
    {
      ACE_Module<ACE_SYNCH_USE> *my_tail = this->stream_head_;

      // Only relink if we still exist!
      if (my_tail)
        {
          // Find the module that's just before our stream tail.
          while (my_tail->next () != this->stream_tail_)
            my_tail = my_tail->next ();

          // Restore the writer's next() link to our tail.
          my_tail->writer ()->next (this->stream_tail_->writer ());
        }

      ACE_Module<ACE_SYNCH_USE> *other_tail =
        this->linked_us_->stream_head_;

      // Only fiddle with the other side if it in fact still remains.
      if (other_tail != 0)
        {
          while (other_tail->next () != this->linked_us_->stream_tail_)
            other_tail = other_tail->next ();

          other_tail->writer ()->next (this->linked_us_->stream_tail_->writer ());

        }

      // Make sure the other side is also aware that it's been unlinked!
      this->linked_us_->linked_us_ = 0;

      this->linked_us_ = 0;
      return 0;
    }
  else
    return -1;
}

template<ACE_SYNCH_DECL >
int ACE_Stream< ACE_SYNCH_DECL >::wait ( void   )  [virtual]

Synchronize with the final close of the stream.

Definition at line 22 of file Stream.inl.

{
  ACE_TRACE ("ACE_Stream<ACE_SYNCH_USE>::wait");
  return this->final_close_.wait ();
}


Friends And Related Function Documentation

template<ACE_SYNCH_DECL >
friend class ACE_Stream_Iterator< ACE_SYNCH_USE > [friend]

Definition at line 52 of file Stream.h.


Member Data Documentation

template<ACE_SYNCH_DECL >
ACE_Stream< ACE_SYNCH_DECL >::ACE_ALLOC_HOOK_DECLARE

Declare the dynamic allocation hooks.

Definition at line 162 of file Stream.h.

template<ACE_SYNCH_DECL >
ACE_SYNCH_CONDITION_T ACE_Stream< ACE_SYNCH_DECL >::final_close_ [private]

Use to tell all threads waiting on the close that we are done.

Definition at line 192 of file Stream.h.

template<ACE_SYNCH_DECL >
ACE_Stream<ACE_SYNCH_USE>* ACE_Stream< ACE_SYNCH_DECL >::linked_us_ [private]

Pointer to an adjoining linked stream.

Definition at line 185 of file Stream.h.

template<ACE_SYNCH_DECL >
ACE_SYNCH_MUTEX_T ACE_Stream< ACE_SYNCH_DECL >::lock_ [private]

Protect the stream against race conditions.

Definition at line 189 of file Stream.h.

template<ACE_SYNCH_DECL >
ACE_Module<ACE_SYNCH_USE>* ACE_Stream< ACE_SYNCH_DECL >::stream_head_ [private]

Pointer to the head of the stream.

Definition at line 179 of file Stream.h.

template<ACE_SYNCH_DECL >
ACE_Module<ACE_SYNCH_USE>* ACE_Stream< ACE_SYNCH_DECL >::stream_tail_ [private]

Pointer to the tail of the stream.

Definition at line 182 of file Stream.h.


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