[omniORB] Time patch for omniorb 2.8

Peter.Ronnquist@nokia.com Peter.Ronnquist@nokia.com
Mon, 21 May 2001 21:37:54 +0300


This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

------_=_NextPart_000_01C0E225.260011E0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


Hello,

We had problems with omniorb 2.8 when we changed the date to some date =
a
number of years into the future.=20
The result was that omniNames got stuck in a loop scanning for=20
<<scavenger.cc>>=20
connections. This is because the method =
omniORB_Scavanger::run_undetached
adds the ScanPeriod to the
absolut time in a loop until the system time is hit.=20

To verifiy this bug just run omniNames -ORBtraceLevel 15, do a date -s =
"1
jan 2001" and then a date -s "19 may 2001", omniNames
will then print out a lot of scanning connections. If I tried to start =
some
corba servers in this state then they could not connect
to the naming server.

Attached to this email is a fix for this problem (just to do a get_time
inside the loop and add the ScanPeriod to that instead).
So the only change is an addtition of:

omni_thread::get_time(&abs_sec, &abs_nsec);

in the end of omniORB_Scavanger::run_undetached(void*)

I don't know if this affects omniOrb 3 as well, but I would be happy if =
this
fix could go into omniOrb2.8.

Best Regards,

Peter R=F6nnquist
Nokia Home Communication
Diskettgatan 11    Tel:  +46 13 461 1353
583 35 Link=F6ping  Cell: +46 709 146874
Sweden               peter.ronnquist@nokia.com
 <<Peter R=F6nnquist (Business Fax).vcf>>=20

------_=_NextPart_000_01C0E225.260011E0
Content-Type: application/octet-stream;
	name="scavenger.cc"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="scavenger.cc"

// -*- Mode: C++; -*-=0A=
//                            Package   : omniORB2=0A=
// scavenger.cc               Created on: 5/8/97=0A=
//                            Author    : Sai Lai Lo (sll)=0A=
//=0A=
//    Copyright (C) 1996-1999 AT&T Laboratories Cambridge=0A=
//=0A=
//    This file is part of the omniORB library=0A=
//=0A=
//    The omniORB library is free software; you can redistribute it =
and/or=0A=
//    modify it under the terms of the GNU Library General Public=0A=
//    License as published by the Free Software Foundation; either=0A=
//    version 2 of the License, or (at your option) any later =
version.=0A=
//=0A=
//    This library is distributed in the hope that it will be =
useful,=0A=
//    but WITHOUT ANY WARRANTY; without even the implied warranty of=0A=
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the =
GNU=0A=
//    Library General Public License for more details.=0A=
//=0A=
//    You should have received a copy of the GNU Library General =
Public=0A=
//    License along with this library; if not, write to the Free=0A=
//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, =
MA  =0A=
//    02111-1307, USA=0A=
//=0A=
//=0A=
// Description:=0A=
//      =0A=
 =0A=
/*=0A=
  $Log: scavenger.cc,v $=0A=
  Revision 1.2  2001/05/19 13:03:27  ronnquis=0A=
  Added get_time to the loop that is scanning for connections. This =
keeps it=0A=
  from counting up to the current time in increments of ScanPeriod (5 =
seconds).=0A=
=0A=
  If the system time was set to be several thousands of seconds in time =
then the=0A=
  nameserver immedialty returned from its timedwait (since the time =
was=0A=
  already passed) then it added ScanPeriod of time to the old time and =
looped=0A=
  again. This lead to that it was  "blocked" until it have looped =
through all=0A=
  seconds.=0A=
=0A=
  Now it gets the system time inside the loop, adds ScanPeriod to that =
and=0A=
  waits for that time. the timedwait will then wait until that time is =
reached=0A=
  (no time out is immediatly triggered).=0A=
=0A=
  Revision 1.1.1.1  2000/04/06 13:18:40  junylund=0A=
=0A=
=0A=
  Revision 1.12  1999/09/23 14:36:33  sll=0A=
  Update from omni2_8_develop=0A=
=0A=
  Revision 1.10.2.1  1999/09/21 20:37:17  sll=0A=
  -Simplified the scavenger code and the mechanism in which =
connections=0A=
   are shutdown. Now only one scavenger thread scans both incoming=0A=
   and outgoing connections. A separate thread do the actual =
shutdown.=0A=
  -omniORB::scanGranularity() now takes only one argument as there =
is=0A=
   only one scan period parameter instead of 2.=0A=
  -Trace messages in various modules have been updated to use the =
logger=0A=
   class.=0A=
  -ORBscanGranularity replaces -ORBscanOutgoingPeriod and=0A=
                                 -ORBscanIncomingPeriod.=0A=
=0A=
  Revision 1.10  1999/08/31 19:22:37  sll=0A=
  Revert back to single inheritance. The bug that causes occasional =
thread=0A=
  exit on startup has been identified. start_undetached() should be =
called=0A=
  from the most derived type. Previously it was called in =
_Scavenger.=0A=
=0A=
  Revision 1.9  1999/08/30 16:49:00  sll=0A=
  Scavenger threads now scan for idle connections and stuck remote =
calls.=0A=
  Another thread Ripper_t is used to do the actual shutdown.=0A=
=0A=
  Revision 1.8  1999/08/16 19:27:20  sll=0A=
  Added a per-compilation unit initialiser object.=0A=
  This object is called by ORB_init and ORB::shutdown.=0A=
=0A=
  Revision 1.7  1999/05/26 11:55:33  sll=0A=
  Use WrTestLock instead of the obsoluted WrTimedLock.=0A=
=0A=
  Revision 1.6  1999/03/11 16:25:55  djr=0A=
  Updated copyright notice=0A=
=0A=
  Revision 1.5  1999/02/11 17:54:19  djr=0A=
  Added class OutScavengerThreadKiller which kills the out scavenger=0A=
  when global destructors are called.=0A=
=0A=
  Revision 1.4  1998/08/14 13:51:58  sll=0A=
  Added pragma hdrstop to control pre-compile header if the compiler =
feature=0A=
  is available.=0A=
=0A=
  Revision 1.3  1998/04/07 19:37:14  sll=0A=
  Replace cerr with omniORB::log.=0A=
=0A=
// Revision 1.2  1998/01/22  11:38:19  sll=0A=
// Set the incoming and outgoing scan period to 30 seconds.=0A=
//=0A=
  Revision 1.1  1997/12/09 18:43:11  sll=0A=
  Initial revision=0A=
=0A=
  */=0A=
=0A=
=0A=
#include <omniORB2/CORBA.h>=0A=
=0A=
#ifdef HAS_pch=0A=
#pragma hdrstop=0A=
#endif=0A=
=0A=
#include <limits.h>=0A=
=0A=
#include <ropeFactory.h>=0A=
#include <objectManager.h>=0A=
#include <scavenger.h>=0A=
=0A=
#define LOGMESSAGE(level,prefix,message) do {\=0A=
   if (omniORB::trace(level)) {\=0A=
     omniORB::logger log("scavenger " ## prefix ## ": ");\=0A=
	log << message ## "\n";\=0A=
   }\=0A=
} while (0)=0A=
=0A=
=0A=
static CORBA::ULong ScanPeriod  =3D 5;		// seconds=0A=
static int serverCallTimeLimit_ =3D 18;=0A=
static int clientCallTimeLimit_ =3D 12;=0A=
static int outIdleTimeLimit_    =3D 24;=0A=
static int inIdleTimeLimit_     =3D 36;=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
// omniORB_Scavenger=0A=
//=0A=
// Instance of this class scan the strands periodically. It calls =
shutdown=0A=
// on those strands that has been idle for a period of time or=0A=
// a call using such a strand has made no progress for a period of =
time.=0A=
// The length of both periods are controlled by the application.=0A=
//=0A=
class omniORB_Scavenger : public omni_thread {=0A=
public:=0A=
  omniORB_Scavenger() : =
pd_cond(&pd_mutex),pd_isdying(0),pd_ropefactories(2) {=0A=
    =0A=
    start_undetached();=0A=
  }=0A=
=0A=
  virtual ~omniORB_Scavenger() {}=0A=
=0A=
  void poke() { pd_cond.signal(); }=0A=
  void kill() { =0A=
    {=0A=
      omni_mutex_lock sync(pd_mutex);=0A=
      pd_isdying =3D 1;=0A=
      pd_cond.signal();=0A=
    }=0A=
    join(0);=0A=
  }=0A=
  =0A=
  void* run_undetached(void*);=0A=
=0A=
  void addRopeFactoryList(ropeFactoryList* l) {=0A=
    omni_mutex_lock sync(pd_mutex);=0A=
    CORBA::ULong index =3D pd_ropefactories.length();=0A=
    pd_ropefactories.length(index + 1);=0A=
    pd_ropefactories[index] =3D l;=0A=
  }=0A=
=0A=
  void removeRopeFactoryList(ropeFactoryList* l) {=0A=
    omni_mutex_lock sync(pd_mutex);=0A=
    CORBA::ULong index;=0A=
    for (index =3D 0; index < pd_ropefactories.length(); index++)=0A=
      if (pd_ropefactories[index] =3D=3D l) break;=0A=
    if (index !=3D pd_ropefactories.length()) {=0A=
      for (index++ ; index < pd_ropefactories.length(); index++)=0A=
	pd_ropefactories[index-1] =3D pd_ropefactories[index];=0A=
      pd_ropefactories.length(pd_ropefactories.length()-1);=0A=
    }=0A=
  }=0A=
=0A=
private:=0A=
  omni_mutex       pd_mutex;=0A=
  omni_condition   pd_cond;=0A=
  CORBA::Boolean   pd_isdying;=0A=
  _CORBA_PseudoValue_Sequence<ropeFactoryList*> pd_ropefactories;=0A=
};=0A=
=0A=
static omniORB_Scavenger* scavenger;=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
// Internal interface to other parts of the ORB=0A=
=0A=
int=0A=
StrandScavenger::clientCallTimeLimit() { return clientCallTimeLimit_; =
}=0A=
=0A=
int =0A=
StrandScavenger::serverCallTimeLimit() { return serverCallTimeLimit_; =
}=0A=
=0A=
int=0A=
StrandScavenger::outIdleTimeLimit() { return outIdleTimeLimit_; }=0A=
=0A=
int=0A=
StrandScavenger::inIdleTimeLimit() { return inIdleTimeLimit_; }=0A=
=0A=
void =0A=
StrandScavenger::addRopeFactories(ropeFactoryList* l) {=0A=
  scavenger->addRopeFactoryList(l);=0A=
}=0A=
=0A=
void=0A=
StrandScavenger::removeRopeFactories(ropeFactoryList* l) {=0A=
  scavenger->removeRopeFactoryList(l);=0A=
}=0A=
=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
void =0A=
omniORB::idleConnectionScanPeriod(omniORB::idleConnType direction,=0A=
				  CORBA::ULong sec)=0A=
{=0A=
  switch (direction)=0A=
    {=0A=
    case omniORB::idleIncoming:=0A=
      if (sec && ScanPeriod)=0A=
	inIdleTimeLimit_ =3D ((sec >=3D ScanPeriod) ? sec : ScanPeriod) / =0A=
                           ScanPeriod;=0A=
      else=0A=
	inIdleTimeLimit_ =3D INT_MAX;=0A=
      break;=0A=
    case omniORB::idleOutgoing:=0A=
      if (sec && ScanPeriod)=0A=
	outIdleTimeLimit_ =3D ((sec >=3D ScanPeriod) ? sec : ScanPeriod)=0A=
                             / ScanPeriod;=0A=
      else=0A=
	outIdleTimeLimit_ =3D INT_MAX;=0A=
      break;=0A=
    }=0A=
}=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
CORBA::ULong =0A=
omniORB::idleConnectionScanPeriod(omniORB::idleConnType direction)=0A=
{=0A=
  switch (direction)=0A=
    {=0A=
    case omniORB::idleIncoming:=0A=
      return ((inIdleTimeLimit_ !=3D INT_MAX) ? =0A=
	      (inIdleTimeLimit_ * ScanPeriod) : 0);=0A=
    case omniORB::idleOutgoing:=0A=
    default:  // stop MSVC complaining=0A=
      return ((outIdleTimeLimit_ !=3D INT_MAX) ? =0A=
	      (outIdleTimeLimit_ * ScanPeriod) : 0);=0A=
    }=0A=
}=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
void =0A=
omniORB::callTimeOutPeriod(omniORB::callTimeOutType direction,=0A=
			   CORBA::ULong sec)=0A=
{=0A=
  switch (direction)=0A=
    {=0A=
    case omniORB::serverSide:=0A=
      if (sec && ScanPeriod)=0A=
	serverCallTimeLimit_ =3D ((sec >=3D ScanPeriod) ? sec : ScanPeriod) / =
=0A=
                               ScanPeriod;=0A=
      else=0A=
	serverCallTimeLimit_ =3D INT_MAX;=0A=
      break;=0A=
    case omniORB::clientSide:=0A=
      if (sec && ScanPeriod)=0A=
	clientCallTimeLimit_ =3D ((sec >=3D ScanPeriod) ? sec : ScanPeriod)=0A=
                                / ScanPeriod;=0A=
      else=0A=
	clientCallTimeLimit_ =3D INT_MAX;=0A=
      break;=0A=
    }=0A=
}=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
CORBA::ULong =0A=
omniORB::callTimeOutPeriod(omniORB::callTimeOutType direction)=0A=
{=0A=
  switch (direction)=0A=
    {=0A=
    case omniORB::serverSide:=0A=
      return ((serverCallTimeLimit_ !=3D INT_MAX) ? =0A=
	      (serverCallTimeLimit_ * ScanPeriod) : 0);=0A=
    case omniORB::clientSide:=0A=
    default:  // stop MSVC complaining=0A=
      return ((clientCallTimeLimit_ !=3D INT_MAX) ? =0A=
	      (clientCallTimeLimit_ * ScanPeriod) : 0);=0A=
    }=0A=
}=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
void =0A=
omniORB::scanGranularity(CORBA::ULong sec)=0A=
{=0A=
  if (sec) {=0A=
    CORBA::ULong clin,ilin,clout,ilout;=0A=
=0A=
    clin =3D omniORB::callTimeOutPeriod(omniORB::serverSide);=0A=
    ilin =3D =
omniORB::idleConnectionScanPeriod(omniORB::idleIncoming);=0A=
    clout =3D omniORB::callTimeOutPeriod(omniORB::clientSide);=0A=
    ilout =3D =
omniORB::idleConnectionScanPeriod(omniORB::idleOutgoing);=0A=
=0A=
    ScanPeriod =3D sec;=0A=
    omniORB::callTimeOutPeriod(omniORB::serverSide,clin);=0A=
    omniORB::idleConnectionScanPeriod(omniORB::idleIncoming,ilin);=0A=
    omniORB::callTimeOutPeriod(omniORB::clientSide,clout);=0A=
    omniORB::idleConnectionScanPeriod(omniORB::idleOutgoing,ilout);=0A=
  }=0A=
  else {=0A=
    ScanPeriod =3D sec;=0A=
  }=0A=
  =0A=
  if (scavenger) {=0A=
    scavenger->poke();=0A=
  }=0A=
}=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
CORBA::ULong =0A=
omniORB::scanGranularity()=0A=
{=0A=
  return ScanPeriod;=0A=
}=0A=
=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
void*=0A=
omniORB_Scavenger::run_undetached(void*)=0A=
{=0A=
  LOGMESSAGE(15,"","start.");=0A=
=0A=
  unsigned long abs_sec,abs_nsec;=0A=
  omni_thread::get_time(&abs_sec,&abs_nsec);=0A=
=0A=
  if (ScanPeriod)=0A=
    abs_sec +=3D ScanPeriod;=0A=
=0A=
  omni_mutex_lock sync(pd_mutex);=0A=
=0A=
  while (!pd_isdying) {=0A=
=0A=
    int poke =3D 0;=0A=
    if (ScanPeriod) {=0A=
      poke =3D pd_cond.timedwait(abs_sec,abs_nsec);=0A=
      if (poke) {=0A=
	LOGMESSAGE(15,"","woken by poke()");=0A=
	omni_thread::get_time(&abs_sec,&abs_nsec);	=0A=
	abs_sec +=3D ScanPeriod;=0A=
      }=0A=
    }=0A=
    else {=0A=
      // inScanPeriod =3D=3D 0 implies stop the scan. Block here =
indefinitely.=0A=
      pd_cond.wait();=0A=
      omni_thread::get_time(&abs_sec,&abs_nsec);	=0A=
    }=0A=
=0A=
    if (poke || pd_isdying) continue;=0A=
  =0A=
    LOGMESSAGE(15,"","scanning connections");=0A=
=0A=
    for (CORBA::ULong i=3D 0; i < pd_ropefactories.length(); i++)=0A=
    {=0A=
      ropeFactory_iterator iter(pd_ropefactories[i]);=0A=
      ropeFactory* rp;=0A=
=0A=
      while ((rp =3D (ropeFactory*)iter())) {=0A=
	// Scan all the outgoing rope=0A=
	Rope_iterator next_rope(rp->anchor());=0A=
	Rope *r;=0A=
	while ((r =3D next_rope())) {=0A=
	  // For each rope, scan all the strands=0A=
	  Strand_iterator next_strand(r);=0A=
	  Strand *s;=0A=
	  while ((s =3D next_strand())) {=0A=
	    if (!s->_strandIsDying() && =0A=
		Strand::Sync::clicksDecrAndGet(s) < 0) {=0A=
	      s->shutdown();=0A=
	    }=0A=
	  }=0A=
	}=0A=
      }=0A=
    }=0A=
=0A=
    // !! PR 2001 may 19, =0A=
    // what if the clock have been set into the future?=0A=
    // This will lead to a loop that increase the abs_sec until the =0A=
    // the actual system time is hit.=0A=
    //abs_sec +=3D ScanPeriod;=0A=
=0A=
    // Ask about the current system time and add the Scan Period.=0A=
    omni_thread::get_time(&abs_sec,&abs_nsec);	=0A=
    abs_sec +=3D ScanPeriod;=0A=
    =0A=
  }=0A=
=0A=
  LOGMESSAGE(15,"","exit.");=0A=
  return 0;=0A=
}=0A=
=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
//            Module initialiser                                        =
   //=0A=
////////////////////////////////////////////////////////////////////////=
/////=0A=
=0A=
class omni_scavenger_initialiser : public omniInitialiser {=0A=
public:=0A=
=0A=
  void attach() {=0A=
    scavenger =3D new omniORB_Scavenger();=0A=
  }=0A=
=0A=
  void detach() {=0A=
    scavenger->kill();=0A=
    scavenger =3D 0;=0A=
  }=0A=
};=0A=
=0A=
static omni_scavenger_initialiser initialiser;=0A=
=0A=
omniInitialiser& omni_scavenger_initialiser_ =3D initialiser;=0A=

------_=_NextPart_000_01C0E225.260011E0
Content-Type: application/octet-stream;
	name="=?iso-8859-1?Q?Peter_R=F6nnquist_=28Business_Fax=29=2E?=
	=?iso-8859-1?Q?vcf?="
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="=?iso-8859-1?Q?Peter_R=F6nnquist_=28Business_Fax=29?=
	=?iso-8859-1?Q?=2Evcf?="

BEGIN:VCARD
VERSION:2.1
N:R=F6nnquist;Peter;;Mr.
FN:Peter R=F6nnquist (Business Fax)
ORG:Nokia Home Communication
TITLE:Software engineer
TEL;WORK;VOICE:+46 (0) 13 461 1353
TEL;HOME;VOICE:+46 (0) 13 211885
TEL;CELL;VOICE:+46 (0) 709 146874
TEL;WORK;FAX:+46 (0) 13 461 1997
ADR;WORK:;;Diskettgatan 11;Link=F6ping;;583 35;Sweden
LABEL;WORK;ENCODING=3DQUOTED-PRINTABLE:Diskettgatan =
11=3D0D=3D0ALink=3DF6ping 583 35=3D0D=3D0ASweden
EMAIL;PREF;FAX:Peter R=F6nnquist@+46 (0) 13 461 1997
REV:20010124T123146Z
END:VCARD

------_=_NextPart_000_01C0E225.260011E0--