[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--