diff options
17 files changed, 208 insertions, 38 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1c52214..77a917b 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 acb7d73..86c1106 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 0024e82..77c8d2c 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 f5e306a..5d0a54f 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 bd58544..1d25117 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 bd74fad..57f6de9 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 367017a..ec2d321 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 316b9f5..07f6529 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 8789b9a..a87bf8f 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 761f9e5..7c5aeab 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 aaaf1d2..3bbff07 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 13574e6..6094158 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 942cb09..9530328 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 a1c9767..ee7aac6 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 38b8320..f944ef2 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 f503979..e4cf7fd 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 4b526e9..79495fb 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 |