text: /*++
  
  Copyright (c) 1995 Microsoft Corporation
  
  Module Name:
  
      soid.hxx
  
  Abstract:
  
      CServerOid objects represent OIDs belonging to processes on the local machine.
      A COid's are reference counted by CServerSets which periodically check if the
      process is still running.
  
  Author:
  
      Mario Goertzel    [MarioGo]
  
  Revision History:
  
      MarioGo     02-22-95    Bits 'n pieces
      MarioGo     04-04-95    Split client and server.
  
  --*/
  
  #ifndef __SOID_HXX
  #define __SOID_HXX
  
  
  class CServerOidPList : public CPList
  {
  public:
      CServerOidPList(ORSTATUS &status) : 
              CPList(status, BaseTimeoutInterval) 
      {}
      
      CServerOid*
      RemoveEligibleOidWithMatchingOxid(CTime &when,
                              CServerOxid* pOxid);
  
      CServerOid*
      RemoveEligibleOid(CTime& when);
  
      void
      ResetAllOidTimeouts();    
  
      BOOL
      AreThereAnyEligibleOidsLyingAround(CTime& when, CServerOxid* pOxid);
  	
  };
  
  class CServerOid : public CIdTableElement
  /*++
  
  Class Description:
  
      Each instance of this class represents an OID registered
      by a server on this machine.  If this OID is not pinged
      by a client for a timeout period it is rundown.
  
  Members:
  
      _pOxid - A pointer to the OXID which registered this OID.
          We own a reference.
  
      _plist - A CPListElement used to manage OID which are not
          part of a client set.  The worker thread uses this
          CPList to manage the rundown on unpinged OIDs.  
  
      _list - A CListElement used to track pinned OIDs.
          
      _fRunningDown - Flag used to prevent multiple threads
          from trying to rundown the same OID multiple times.
          Only 1 bit is required.
  
      _fFreed - Flag used to remember when the owning apartment has
          deregistered this oid.
      
      _fPinned -- TRUE if we received a ORS_OID_PINNED status the last
          time we tried to rundown this stub.
  
  --*/
      {
    friend class CServerOidPList;
  
    private :
  
      CServerOxid   *_pOxid;
      CPListElement  _plist;
      CListElement   _list;
      BOOL           _fRunningDown:1;
      BOOL           _fFreed:1;
      BOOL           _fPinned:1;
  
    public :
  
      CServerOid(CServerOxid *oxid, ID id) :
          CIdTableElement(id), 
          _pOxid(oxid),
          _fRunningDown(FALSE),
          _fFreed(FALSE),
          _fPinned(FALSE)
          {
          _pOxid->Reference();
          }
  
      ~CServerOid();
  
      void KeepAlive();
  
      void SetRundown(BOOL fRunningDown)
          {
          ASSERT(gpServerLock->HeldExclusive());
          ASSERT(_plist.NotInList());
          _fRunningDown = fRunningDown;
          }
  
      BOOL Match(CServerOid *pOid)
          {
          return(pOid->_pOxid == _pOxid);
          }
  
      BOOL IsRunning()
          {
          ASSERT(_pOxid);
          return(_pOxid->IsRunning());
          }
  
      BOOL IsRunningDown()
          {
          return(_fRunningDown);
          }
  
      CServerOxid *GetOxid()
          {
          return(_pOxid);
          }
  
      void Reference();
  
      DWORD Release();
  
      static CServerOid *ContainingRecord(CListElement *ple) {
          return CONTAINING_RECORD(ple, CServerOid, _plist);
          }
      
      static CServerOid *ContainingRecord2(CListElement *ple) {
          return CONTAINING_RECORD(ple, CServerOid, _list);
          }
  
      void Insert() {
          ASSERT(gpServerLock->HeldExclusive());
          ASSERT(IsRunningDown() == FALSE);
          ASSERT(_plist.NotInList());
          ASSERT(_list.NotInList());
          gpServerOidPList->Insert(&_plist);
          }
  
      CPListElement *Remove() {
          ASSERT(gpServerLock->HeldExclusive());
          // We may or may not be in the oid plist, so don't
          // assert on that.
          ASSERT(_list.NotInList());
          return(gpServerOidPList->Remove(&_plist));
          }
  
      void Free() {
          ASSERT(gpServerLock->HeldExclusive());
          _fFreed = TRUE;
  
          // If pinned, unpin.
          if (IsPinned())
              SetPinned(FALSE);
          }
  
      BOOL IsFreed() {
          return(_fFreed);
          }
  
      void SetPinned(BOOL fPinned);
  
      BOOL IsPinned() {
          return (_fPinned);
          }
  
      };
  
  #endif // __SOID_HXX
  
  