diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1c522145fb311ca38b448e62c86f5be9b937f5be..77a917b78ed76e6b63b70925c37cd2578e8f652a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,33 @@ +2005-01-03 Mark Mitchell <mark@codesourcery.com> + + * configure.ac: Check for sys/ipc.h and sys/sem.h. + * config.h.in: Regenerated. + * configure: Likewise. + * testsuite/testsuite_hooks.cc (_GLIBCXX_SYSV_SEM): Conditionally + define. + (sys/types.h): Include. + (sys/ipc.h): Likewise. + (sys/sem.h): Likewise. + (__gnu_test::semun): New type. + (__gnu_test::semaphore::sempaphore): New function. + (__gnu_test::semaphore::~semaphore): Likewise. + (__gnu_test::semaphore::wait): Likewise. + (__gnu_test::semaphore::signal): Likewise. + * testsuite/testsuite_hooks.h (__gnu_test::semaphore): New class. + * testsuite/27_io/basic_filebuf/close/char/4789.cc: Use + semaphores, not sleep. + * testsuite/27_io/basic_filebuf/close/char/9964.cc: Likewise. + * testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc: Likewise. + * testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc: Likewise. + * testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc: + Likewise. + * testsuite/27_io/basic_filebuf/open/char/9507.cc: Likewise. + * testsuite/27_io/basic_filebuf/underflow/char/10097.cc: Likewise. + * testsuite/27_io/objects/char/7.cc: Likewise. + * testsuite/27_io/objects/char/9661-1.cc: Likewise. + * testsuite/27_io/objects/wchar_t/7.cc: Likewise. + * testsuite/27_io/objects/wchar_t/9961-1.cc: Likewise. + 2005-01-03 Paolo Carlini <pcarlini@suse.de> * include/bits/istream.tcc (ignore(streamsize), ignore(streamsize, diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index acb7d732abc2951f7b318f3dea12f54e4d24a685..86c110648726d122b6bbe18f17b1727ba6e10f90 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -506,6 +506,9 @@ /* Define to 1 if you have the <sys/ioctl.h> header file. */ #undef HAVE_SYS_IOCTL_H +/* Define to 1 if you have the <sys/ipc.h> header file. */ +#undef HAVE_SYS_IPC_H + /* Define to 1 if you have the <sys/isa_defs.h> header file. */ #undef HAVE_SYS_ISA_DEFS_H @@ -518,6 +521,9 @@ /* Define to 1 if you have the <sys/resource.h> header file. */ #undef HAVE_SYS_RESOURCE_H +/* Define to 1 if you have the <sys/sem.h> header file. */ +#undef HAVE_SYS_SEM_H + /* Define to 1 if you have the <sys/stat.h> header file. */ #undef HAVE_SYS_STAT_H diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 0024e82faa2e9e6b9e7608fc12d53afd9badacfe..77c8d2c4fa05c15f631380e4cba249c24bc11f62 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -7927,9 +7927,11 @@ if $GLIBCXX_IS_NATIVE; then + + for ac_header in nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \ machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \ - sys/types.h + sys/types.h sys/ipc.h sys/sem.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if eval "test \"\${$as_ac_Header+set}\" = set"; then diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index f5e306acc262ae796634ae144c2b8de3e036426d..5d0a54f9c4cf2b2f8f4c7a80054025fdb00b999f 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -117,7 +117,7 @@ if $GLIBCXX_IS_NATIVE; then # Check for available headers. AC_CHECK_HEADERS([nan.h ieeefp.h endian.h sys/isa_defs.h machine/endian.h \ machine/param.h sys/machine.h fp.h locale.h float.h inttypes.h gconv.h \ - sys/types.h]) + sys/types.h sys/ipc.h sys/sem.h]) GLIBCXX_CHECK_COMPILER_FEATURES GLIBCXX_CHECK_LINKER_FEATURES diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/4879.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/4879.cc index bd585443be1b62139d646e76cffb02fe87542b06..1d251174099a3cd9129d79dfbac6dd252f907b27 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/4879.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/4879.cc @@ -41,6 +41,8 @@ test_04() bool test __attribute__((unused)) = true; const char* name = "tmp_fifo1"; + semaphore s1, s2; + signal(SIGPIPE, SIG_IGN); unlink(name); @@ -60,13 +62,15 @@ test_04() else if (fval == 0) { std::ifstream ifs(name); - sleep(1); + s1.wait (); ifs.close(); + s2.signal (); exit(0); } std::ofstream ofs(name); - sleep(2); + s1.signal (); + s2.wait (); ofs.put('t'); /* diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/9964.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/9964.cc index bd74fad34bf07d9fbb195305db73b6d756d5c099..57f6de9c5ee61b7d8355884013198d101cffac74 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/9964.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/close/char/9964.cc @@ -37,6 +37,7 @@ void test_07() using namespace std; using namespace __gnu_test; bool test __attribute__((unused)) = true; + semaphore s1, s2; const char* name = "tmp_fifo3"; @@ -52,18 +53,18 @@ void test_07() { filebuf fbin; fbin.open(name, ios_base::in); - sleep(2); + s1.wait (); fbin.close(); + s2.signal (); exit(0); } filebuf fb; - sleep(1); filebuf* ret = fb.open(name, ios_base::in | ios_base::out); VERIFY( ret != NULL ); VERIFY( fb.is_open() ); - - sleep(3); + s1.signal (); + s2.wait (); fb.sputc('a'); ret = fb.close(); diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc index 367017a3bfef6ac5ae11a33f1ef30afca849ecba..ec2d321bbf5d023265da79b0533dda8f1ad28d35 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc @@ -39,6 +39,7 @@ void test01() const char* name = "tmp_fifo_13171-2"; unlink(name); try_mkfifo(name, S_IRWXU); + semaphore s1, s2; int child = fork(); if (child == 0) @@ -47,7 +48,8 @@ void test01() fb.open(name, ios_base::out); fb.sputc('S'); fb.pubsync(); - sleep(2); + s1.signal (); + s2.wait (); fb.close(); exit(0); } @@ -55,12 +57,13 @@ void test01() filebuf fb; fb.pubimbue(loc_fr); fb.open(name, ios_base::in); - sleep(1); + s1.wait (); VERIFY( fb.is_open() ); fb.pubimbue(loc_en); filebuf::int_type c = fb.sgetc(); fb.close(); VERIFY( c == 'S' ); + s2.signal (); } int main() diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc index 316b9f59735df87db66ab00e26253291e05857cf..07f6529de4aa1912906574520c636889f380fe6a 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13582-2.cc @@ -42,7 +42,7 @@ void test01() const char* name = "tmp_fifo_13582-2"; unlink(name); try_mkfifo(name, S_IRWXU); - + int child = fork(); if (child == 0) { @@ -50,14 +50,12 @@ void test01() fbout.open(name, ios_base::out); fbout.sputn("12345", 5); fbout.pubsync(); - sleep(2); fbout.close(); exit(0); } filebuf fbin; fbin.open(name, ios_base::in); - sleep(1); filebuf::int_type n = fbin.sbumpc(); VERIFY( n == '1' ); fbin.pubimbue(loc_en); diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc index 8789b9aa4d8eebab681d673e9006cade67c519d4..a87bf8ffd60fb8ee1016c0703ce6feffb8ee5cca 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/14975-2.cc @@ -42,26 +42,28 @@ void test01() unlink(name); try_mkfifo(name, S_IRWXU); - + semaphore s1; + int child = fork(); VERIFY( child != -1 ); if (child == 0) { - filebuf fbin; - fbin.open(name, ios_base::in); - sleep(2); + { + filebuf fbin; + fbin.open(name, ios_base::in); + } + s1.signal (); exit(0); } wfilebuf fb; fb.pubimbue(loc_us); - sleep(1); wfilebuf* ret = fb.open(name, ios_base::out); VERIFY( ret != NULL ); VERIFY( fb.is_open() ); - sleep(3); + s1.wait (); try { diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/open/char/9507.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/open/char/9507.cc index 761f9e585f0a3660a8f9b8acc2cc4ba9ea3ff0a1..7c5aeab5d87e357c952a29eeb8bd1282c025dfa0 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/open/char/9507.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/open/char/9507.cc @@ -37,30 +37,33 @@ void test_06() using namespace __gnu_test; bool test __attribute__((unused)) = true; const char* name = "tmp_fifo2"; + semaphore s1, s2; signal(SIGPIPE, SIG_IGN); unlink(name); try_mkfifo(name, S_IRWXU); - + if (!fork()) { std::filebuf fbuf; fbuf.open(name, std::ios_base::in); fbuf.sgetc(); - sleep(2); + s1.signal (); fbuf.close(); + s2.wait (); exit(0); } std::filebuf fbuf; - sleep(1); std::filebuf* r = fbuf.open(name, std::ios_base::in | std::ios_base::out | std::ios_base::ate); + s1.wait (); VERIFY( !fbuf.is_open() ); VERIFY( r == NULL ); + s2.signal (); } int diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/char/10097.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/char/10097.cc index aaaf1d2d7b64f2bd58807c4c3938b0f37562a4ec..3bbff078f8e91c2e19e285729363211484eb148c 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/char/10097.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/underflow/char/10097.cc @@ -58,6 +58,7 @@ void test16() VERIFY( false ); } + semaphore s1; int fval = fork(); if (fval == -1) { @@ -71,14 +72,13 @@ void test16() VERIFY ( fbout.is_open() ); fbout.sputn("0123456789", 10); fbout.pubsync(); - sleep(2); + s1.wait (); fbout.close(); exit(0); } UnderBuf fb; fb.open(name, ios_base::in); - sleep(1); fb.sgetc(); streamsize n = fb.pub_showmanyc(); @@ -94,6 +94,7 @@ void test16() } fb.close(); + s1.signal (); } int main() diff --git a/libstdc++-v3/testsuite/27_io/objects/char/7.cc b/libstdc++-v3/testsuite/27_io/objects/char/7.cc index 13574e67c92f5cf1918755ff9c72721f59060107..609415882b6be76df141322f716e87debafe8b29 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/7.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/7.cc @@ -42,26 +42,26 @@ void test07() unlink(name); try_mkfifo(name, S_IRWXU); - + semaphore s1; + int child = fork(); VERIFY( child != -1 ); if (child == 0) { filebuf fbout; - sleep(1); fbout.open(name, ios_base::in|ios_base::out); + s1.wait (); VERIFY ( fbout.is_open() ); cout.rdbuf(&fbout); fbout.sputc('a'); - sleep(2); // NB: fbout is *not* destroyed here! exit(0); } filebuf fbin; fbin.open(name, ios_base::in); - sleep(2); + s1.signal (); filebuf::int_type c = fbin.sbumpc(); VERIFY( c != filebuf::traits_type::eof() ); VERIFY( c == filebuf::traits_type::to_int_type('a') ); diff --git a/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc b/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc index 942cb09438960189be221a90bd95bc6ec0f232a8..9530328afc9aeff78ab86dacfbeae8320f72b604 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/9661-1.cc @@ -43,24 +43,25 @@ void test01() unlink(name); try_mkfifo(name, S_IRWXU); + semaphore s1, s2; int child = fork(); VERIFY( child != -1 ); if (child == 0) { - sleep(1); FILE* file = fopen(name, "r+"); VERIFY (file != NULL); fputs("Whatever\n", file); fflush(file); - sleep(2); + s1.signal (); + s2.wait (); fclose(file); exit(0); } freopen(name, "r", stdin); - sleep(2); + s1.wait (); int c1 = fgetc(stdin); VERIFY( c1 != EOF ); @@ -78,6 +79,7 @@ void test01() int c5 = cin.rdbuf()->sgetc(); VERIFY( c5 != EOF ); VERIFY( c5 == c4 ); + s2.signal (); } int main() diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/7.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/7.cc index a1c97670038aea3e42b1f4446517a6fa6788354a..ee7aac6ec1661ba779e0f4f67ff6d1c809e3b636 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/7.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/7.cc @@ -42,6 +42,7 @@ void test07() unlink(name); try_mkfifo(name, S_IRWXU); + semaphore s1; int child = fork(); VERIFY( child != -1 ); @@ -49,18 +50,17 @@ void test07() if (child == 0) { wfilebuf fbout; - sleep(1); fbout.open(name, ios_base::out); + s1.wait(); wcout.rdbuf(&fbout); fbout.sputc(L'a'); - sleep(2); // NB: fbout is *not* destroyed here! exit(0); } wfilebuf fbin; fbin.open(name, ios_base::in); - sleep(2); + s1.signal (); wfilebuf::int_type c = fbin.sbumpc(); VERIFY( c != wfilebuf::traits_type::eof() ); VERIFY( c == wfilebuf::traits_type::to_int_type(L'a') ); diff --git a/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc b/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc index 38b832049b873a4efde834fa874e43152ebb5d72..f944ef2524aa21c5e6f27b33300e70a4086be188 100644 --- a/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc +++ b/libstdc++-v3/testsuite/27_io/objects/wchar_t/9661-1.cc @@ -43,23 +43,24 @@ void test01() unlink(name); try_mkfifo(name, S_IRWXU); - + semaphore s1, s2; + int child = fork(); VERIFY( child != -1 ); if (child == 0) { - sleep(1); FILE* file = fopen(name, "w"); fputs("Whatever\n", file); fflush(file); - sleep(2); + s1.signal (); + s2.wait (); fclose(file); exit(0); } freopen(name, "r", stdin); - sleep(2); + s1.wait (); wint_t c1 = fgetwc(stdin); VERIFY( c1 != WEOF ); @@ -77,6 +78,7 @@ void test01() wint_t c5 = wcin.rdbuf()->sgetc(); VERIFY( c5 != WEOF ); VERIFY( c5 == c4 ); + s2.signal (); } int main() diff --git a/libstdc++-v3/testsuite/testsuite_hooks.cc b/libstdc++-v3/testsuite/testsuite_hooks.cc index f503979b65d85d2ca8aec98606e654bd801d42f0..e4cf7fdd7a7085dfdbf00ce58564f561335912a7 100644 --- a/libstdc++-v3/testsuite/testsuite_hooks.cc +++ b/libstdc++-v3/testsuite/testsuite_hooks.cc @@ -42,6 +42,20 @@ #include <locale> #include <cxxabi.h> +// If we have <sys/types.h>, <sys/ipc.h>, and <sys/sem.h>, then assume +// that System V semaphores are available. +#if defined(_GLIBCXX_HAVE_SYS_TYPES_H) \ + && defined(_GLIBCXX_HAVE_SYS_IPC_H) \ + && defined(_GLIBCXX_HAVE_SYS_SEM_H) +#define _GLIBCXX_SYSV_SEM +#endif + +#ifdef _GLIBCXX_SYSV_SEM +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#endif + namespace __gnu_test { #ifdef _GLIBCXX_RES_LIMITS @@ -252,6 +266,84 @@ namespace __gnu_test unsigned int assignment_operator::throw_on_ = 0; unsigned int destructor::_M_count = 0; int copy_tracker::next_id_ = 0; + +#ifdef _GLIBCXX_SYSV_SEM + // This union is not declared in system headers. Instead, it must + // be defined by user programs. + union semun + { + int val; + struct semid_ds *buf; + unsigned short *array; + }; +#endif + + semaphore::semaphore () + { +#ifdef _GLIBCXX_SYSV_SEM + // Remeber the PID for the process that created the semaphore set + // so that only one process will destroy the set. + pid_ = getpid(); + + // GLIBC does not define SEM_R and SEM_A. +#ifndef SEM_R +#define SEM_R 0400 +#endif + +#ifndef SEM_A +#define SEM_A 0200 +#endif + + // Get a semaphore set with one semaphore. + sem_set_ = semget (IPC_PRIVATE, 1, SEM_R | SEM_A); + if (sem_set_ == -1) + throw std::runtime_error ("could not obtain semaphore set"); + + // Initialize the semaphore. + union semun val; + val.val = 0; + if (semctl (sem_set_, 0, SETVAL, val) == -1) + throw std::runtime_error ("could not initialize semaphore"); +#else + // There are no semaphores on this system. We have no way to mark + // a test as "unsupported" at runtime, so we just exit, pretending + // that the test passed. + exit (0); +#endif + } + + semaphore::~semaphore () + { +#ifdef _GLIBCXX_SYSV_SEM + union semun val; + // Destroy the semaphore set only in the process that created it. + if (pid_ == getpid ()) + semctl (sem_set_, 0, IPC_RMID, val); +#endif + } + + void + semaphore::signal () + { +#ifdef _GLIBCXX_SYSV_SEM + struct sembuf op[1] = { + { 0, 1, 0 } + }; + if (semop (sem_set_, op, 1) == -1) + throw std::runtime_error ("could not signal semaphore"); +#endif + } + + void + semaphore::wait() { +#ifdef _GLIBCXX_SYSV_SEM + struct sembuf op[1] = { + { 0, -1, SEM_UNDO } + }; + if (semop (sem_set_, op, 1) == -1) + throw std::runtime_error ("could not wait for semaphore"); +#endif + } }; // namespace __gnu_test namespace std diff --git a/libstdc++-v3/testsuite/testsuite_hooks.h b/libstdc++-v3/testsuite/testsuite_hooks.h index 4b526e9b19f0bcc6e1526ace4fe11ae8d48b0eea..79495fbd357caba0d86f5eb9734f6f6773436e24 100644 --- a/libstdc++-v3/testsuite/testsuite_hooks.h +++ b/libstdc++-v3/testsuite/testsuite_hooks.h @@ -380,6 +380,30 @@ namespace __gnu_test return it == end ? v.end() : it; } }; + + // A binary semaphore for use across multiple processes. + class semaphore + { + public: + // Creates a binary semaphore. The semaphore is initially in the + // unsignaled state. + semaphore (); + + // Destroy the semaphore. + ~semaphore(); + + // Signal the semaphore. If there are processes blocked in + // "wait", exactly one will be permitted to proceed. + void signal (); + + // Wait until the semaphore is signaled. + void wait (); + + private: + int sem_set_; + + pid_t pid_; + }; } // namespace __gnu_test namespace std