[Pkg-ace-devel] Bug#524922: libace-dev: semaphores occasionally fail

Paul Fitzpatrick paulfitz at liralab.it
Mon Apr 20 20:13:48 UTC 2009


Subject: libace-dev: semaphores occasionally fail
Package: libace-dev
Version: 5.6.3-5
Severity: normal

*** Please type your report below this line ***

Semaphores created with the ACE_Semaphore class have become unreliable.  
In the test program I give below, the call to sema->acquire() fails 
reliably with errno 38.  Running on an old (version 5.5) version of ACE,
compiled by hand, the program succeeds without problem.  It also 
succeeds if I use sem_t semaphores directly (uncomment the 
"USE_NATIVE_POSIX_SEMA" line at the beginning to see this).

I can't quite put my finger on what has changed that causes this 
problem.  Usually semaphore failure happens in quite complicated
scenarios; it took a long time to pare it down to the example 
below (see the "allocateSomething" method, which should be a no-op,
but affects the result).  Any help would be appreciated.

I compile this test with:
  g++ acecheck.cpp `pkg-config --libs --cflags ACE` -o acecheck
Adding -D_REENTRANT does not affect the behavior.


//////////////////////////////////////////////////
// Test program "acecheck.cpp" begins

//#define USE_NATIVE_POSIX_SEMA

#include <ace/ACE.h>
#include <ace/OS.h>
#include <ace/Synch.h>
#include <ace/Thread.h>
#include <ace/String_Base.h>

#include <stdio.h>

#ifdef USE_NATIVE_POSIX_SEMA
#include <semaphore.h>
#endif

int subTestDone = 0;
int mainTestDone = 0;

unsigned int subTestThread(void *args) {
    ACE_OS::printf("subTestThread started.\n");
#ifdef USE_NATIVE_POSIX_SEMA
    sem_t *sema = (sem_t *)args;
    int result = sem_wait(sema);
#else
    ACE_Semaphore *sema = (ACE_Semaphore *)args;
    int result = sema->acquire();
#endif
    if (result==-1) {
        ACE_OS::printf("SEMAPHORE ERROR! %d\n", ACE_OS::last_error());
        ACE_OS::exit(1);
    }
    ACE_OS::printf("subTestThread finished.\n");
    subTestDone = 1;
    return 0;
}

unsigned int mainTestThread(void *args) {
    ACE_OS::printf("mainTestThread started.\n");

#ifdef USE_NATIVE_POSIX_SEMA
    sem_t sema;
    sem_init(&sema,0,0);
#else
    ACE_Semaphore sema(0);
#endif

    int result = ACE_Thread::spawn((ACE_THR_FUNC)subTestThread,
                                   (void *)(&sema),
                                   THR_JOINABLE | THR_NEW_LWP,
                                   NULL,
                                   NULL,
                                   ACE_DEFAULT_THREAD_PRIORITY,
                                   0,
                                   (size_t)0);
    if (result!=0) {
        ACE_OS::printf("THREAD ERROR!\n");
        ACE_OS::exit(1);
    }
    ACE_OS::printf("mainTestThread pausing.\n");
    ACE_OS::sleep(1);
    ACE_OS::printf("mainTestThread unpaused.\n");
#ifdef USE_NATIVE_POSIX_SEMA
    sem_post(&(sema));
#else
    sema.release();
#endif
    while (!subTestDone) {
        ACE_OS::sleep(1);
    }

#ifdef USE_NATIVE_POSIX_SEMA
    sem_destroy(&sema);
#endif

    ACE_OS::printf("mainTestThread finished.\n");
    mainTestDone = 1;
    return 0;
};


// This helps tickle the bug, but doesn't seem to be always essential.
// I have *no* *idea* what is going on here.
void allocateSomething() {
    ACE_String_Base<char> *s = new ACE_String_Base<char>;
    delete s;
}


int main() {
    ACE::init();

    allocateSomething();

    int result = ACE_Thread::spawn((ACE_THR_FUNC)mainTestThread,
                                   NULL,
                                   THR_JOINABLE | THR_NEW_LWP,
                                   NULL,
                                   NULL,
                                   ACE_DEFAULT_THREAD_PRIORITY,
                                   0,
                                   (size_t)0);
    if (result!=0) {
        ACE_OS::printf("THREAD ERROR!\n");
        ACE_OS::exit(1);
    }
    while (!mainTestDone) {
        ACE_OS::sleep(1);
    }

    ACE::fini();
    return 0;
}

// Test program ends
//////////////////////////////////////////////////

Run as is, with the ACE semaphore wrapper in use, the results I see 
are:
   mainTestThread started.
   subTestThread started.
   SEMAPHORE ERROR! 38
This is bad.  Run with the "USE_NATIVE_POSIX_SEMA" line uncommented,
the results I see are:
   mainTestThread started.
   subTestThread started.
   mainTestThread pausing.
   mainTestThread unpaused.
   subTestThread finished.
   mainTestThread finished.
 This is good.



-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-cam (SMP w/1 CPU core)
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)
Shell: /bin/sh linked to /bin/bash

Versions of packages libace-dev depends on:
ii  libace-5.6.3                  5.6.3-5    C++ network programming framework

libace-dev recommends no packages.

-- no debconf information





More information about the Pkg-ace-devel mailing list