Replace/remove all the explanatory text in brackets before mailing.
ACE VERSION: 4.6
HOST MACHINE and OPERATING SYSTEM:
Linux uzi.atdesk.com 2.0.34 #9 Fri Nov 13 14:37:47 EST 1998 i686 unknown
TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
COMPILER NAME AND VERSION:
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.57/specs
gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
AREA/CLASS/EXAMPLE AFFECTED:
ACE_OS::mktime() and ACE_OS::getservbyname_r()
SYNOPSIS:
Program hangs on call to ACE_OS::getservbyname_r() after ACE_OS::mktime()
has been called. Only happens if ACE is built multithread enabled.
DESCRIPTION:
The following test program demonstrates an example where the program calls
ACE_OS::mktime(). After that, the program calls ACE_OS::getservbyname_r(),
and that call hangs (i.e. never returns).
If I replace ACE_OS::mktime() with ::mktime() the program functions as
expected.
REPEAT BY:
Here is a test program.
#include "ace/SOCK_Connector.h"
#include "ace/INET_Addr.h"
#include "ace/Thread.h"
#include "ace/OS.h"
#include "ace/Read_Buffer.h"
#include "ace/Synch_T.h"
#include "ace/Synch.h"
#define SHOW_BUG
unsigned int baseTime;
int main (int argc, char ** argv)
{
servent sentry;
servent *sp;
ACE_SERVENT_DATA buf;
cerr << __FILE__ << ": " << __LINE__ << endl;
time_t timeNow = ACE_OS::time();
tm t;
ACE_OS::localtime_r(&timeNow, &t);
t.tm_hour = t.tm_min = t.tm_sec = 0;
#if defined(SHOW_BUG)
baseTime = (unsigned int)ACE_OS::mktime(&t);
#else
baseTime = (unsigned int)::mktime(&t);
#endif
cerr << __FILE__ << ": " << __LINE__ << endl;
sp = ACE_OS::getservbyname_r ("otchitter", "tcp", &sentry, buf);
ACE_OS::localtime_r(&timeNow, &t);
cerr << __FILE__ << ": " << __LINE__ << endl;
for (;;)
{
cerr << __FILE__ << ": " << __LINE__ << endl;
ACE_OS::sleep(2);
}
}
SAMPLE FIX/WORKAROUND:
Use ::mktime() instead of ACE_OS::mktime().
> HOST MACHINE and OPERATING SYSTEM:
> Linux uzi.atdesk.com 2.0.34 #9 Fri Nov 13 14:37:47 EST 1998 i686 unknown
> AREA/CLASS/EXAMPLE AFFECTED:
> ACE_OS::mktime() and ACE_OS::getservbyname_r()
>
> SYNOPSIS:
> Program hangs on call to ACE_OS::getservbyname_r() after ACE_OS::mktime()
> has been called. Only happens if ACE is built multithread enabled.
>
> DESCRIPTION:
> The following test program demonstrates an example where the program calls
> ACE_OS::mktime(). After that, the program calls ACE_OS::getservbyname_r(),
> and that call hangs (i.e. never returns).
>
> If I replace ACE_OS::mktime() with ::mktime() the program functions as
> expected.
How strange. ACE_OS::mktime () is thread safe; ::mktime () isn't.
ACE_OS::mktime () just guards ::mktime ():
ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock =
ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object
(ACE_Object_Manager::ACE_OS_MONITOR_LOCK);
ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock, (time_t) -1));
ACE_OSCALL_RETURN (::mktime (t), time_t, (time_t) -1);
If you remove the ACE_GUARD_RETURN (in OS.cpp) and rebuild your
libACE, does your program work properly?
Have you tried this on any other platforms?
Thanks,
David
I tried on SunOS 5.7 and Linux 2.0.36, and it succeeded on
both.
Do you have a newer Linux installation to test on?
Thanks,
David
David Levine <lev...@cs.wustl.edu> wrote in article
<1999010719...@danzon.cs.wustl.edu>...
> > If I replace ACE_OS::mktime() with ::mktime() the program functions as
> > expected.
>
> How strange. ACE_OS::mktime () is thread safe; ::mktime () isn't.
> ACE_OS::mktime () just guards ::mktime ():
>
> ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock =
> ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object
> (ACE_Object_Manager::ACE_OS_MONITOR_LOCK);
> ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock,
(time_t) -1));
>
> ACE_OSCALL_RETURN (::mktime (t), time_t, (time_t) -1);
>
> If you remove the ACE_GUARD_RETURN (in OS.cpp) and rebuild your
> libACE, does your program work properly?
If I comment out the entire ACE_MT macro (of which ACE_GUARD_RETURN is a
part) then the program works. I suspect some weird interaction with this
locking mechanism.
Note that the test program only has a single thread. However, the same
thing happens if I have other threads. I can spin off a worker thread that
sleeps and wakes up every second. It works, but the main thread will still
see this same problem.
>
> Have you tried this on any other platforms?
No. I only have ACE on Linux at present.
>
> I tried on SunOS 5.7 and Linux 2.0.36, and it succeeded on
> both.
>
> Do you have a newer Linux installation to test on?
What egcs did you use? Also, in the normal ACE tests directory, there is a
test that hangs under linux. Does that hang go away under your 2.0.36
setup? I do have a 2.0.35 machine around here, but I don't know if I can
put ACE on it. I'll see.
> What egcs did you use?
The version that ships with RedHat 5.2, egcs 1.0.3.
> Also, in the normal ACE tests directory, there is a
> test that hangs under linux. Does that hang go away under your 2.0.36
> setup?
No. It sounds like you're using an old egcs version, which
do have problems with ACE on Linux. Please see
ACE-INSTALL.html for recommended versions.
Thanks,
David