void IntQueue::pushInt(int n)
{
    d_mutexSem.wait();
    d_queue.push_front(n);
    d_mutexSem.post();
    d_resourceSem.post();
}
int IntQueue::getInt()
{
    // Waiting for resources.
    d_resourceSem.wait();

    // 'd_mutexSem' is used for exclusive access.
    d_mutexSem.wait();
    int ret = d_queue.back();
    d_queue.pop_back();
    d_mutexSem.post();

    return ret;
}
int main(int argc, char *argv[]) {

    int test = argc > 1 ? atoi(argv[1]) : 0;
    int verbose = argc > 2;

    cout << "TEST " << __FILE__ << " CASE " << test << endl;

    switch (test) { case 0:  // Zero is always the leading case.
      case 6: {
///Usage
///-----
// This component is an implementation detail of 'bslmt' and is *not* intended
// for direct client use.  It is subject to change without notice.  As such, a
// usage example is not provided.

        // USAGE EXAMPLE
        IntQueue testQueue;

        testQueue.pushInt(1);
        ASSERT(1 == testQueue.getInt());
        testQueue.pushInt(2);
        ASSERT(2 == testQueue.getInt());

      } break;
      case 5: {
        // --------------------------------------------------------------------
        // TESTING 'tryWait'
        //
        // Concerns:
        //   1. 'tryWait' decrements the count if resources are available,
        //      or return an error otherwise.
        //
        // Plan:
        //   We create two groups of threads.  One will call 'post', the other
        //   'tryWait'.  First, we make sure that 'tryWait' fails if no
        //   resources are available.  Then we will make sure it succeeds if
        //   resources are.  We will also test 'tryWait' in the steady state
        //   works fine.
        //
        // Testing:
        //   void tryWait();
        // --------------------------------------------------------------------

        if (verbose) cout << endl
                          << "Testing 'trywait'" << endl
                          << "=================" << endl;

        bslmt::ThreadUtil::Handle threads[10];
        MyBarrier barrier(10);
        Obj sem;

        struct ThreadInfo5 info;
        info.d_numIterations = 5000; // number of ops per thread / 3
        info.d_barrier = &barrier;
        info.d_sem = &sem;

        for (int i = 0; i < 5; ++i) {
            ASSERT(0 == bslmt::ThreadUtil::create(&threads[i * 2],
                                                 thread5Post,
                                                 &info));

            ASSERT(0 == bslmt::ThreadUtil::create(&threads[i * 2 + 1],
                                                   thread5Wait,
                                                   &info));
        }
        for (int i = 0; i < 10; ++i) {
            ASSERT(0 == bslmt::ThreadUtil::join(threads[i]));
        }

      } break;
      case 4: {
        // --------------------------------------------------------------------
        // TESTING 'post(int)'
        //
        // Concerns:
        //   1. post(int) increments the count by the expected number
        //
        // Plan:
        //   Create a set of threads calling 'wait' and use a thread to post a
        //   number smaller than the set of threads.
        //
        // Testing:
        //   void post(int number);
        // --------------------------------------------------------------------

        if (verbose) cout << endl
                          << "Testing 'post(int number)'" << endl
                          << "==========================" << endl;

        bslmt::ThreadUtil::Handle threads[6];
        MyBarrier barrier(6);
        Obj sem;

        struct ThreadInfo4 info;
        info.d_numIterations = 10000; // number of ops per thread
        info.d_numWaitThreads = 5;
        info.d_barrier = &barrier;
        info.d_sem = &sem;

        for (int i = 0; i < 5; ++i) {
            ASSERT(0 == bslmt::ThreadUtil::create(&threads[i],
                                                 thread4Wait,
                                                 &info));
        }
        ASSERT(0 == bslmt::ThreadUtil::create(&threads[5],
                                             thread4Post,
                                             &info));
        for (int i = 0; i < 6; ++i) {
            ASSERT(0 == bslmt::ThreadUtil::join(threads[i]));
        }

      } break;
      case 3: {
        // --------------------------------------------------------------------
        // TESTING 'timedWait'
        //
        // Concerns:
        //   1. timedWait() blocks the thread until a resource is available
        //      or the timeout expires.
        //
        // Plan:
        //  Create two groups of threads one will call 'post' and the other
        //  will call 'timedWait'.  First, we will make sure that the
        //  'timedWait' will timeout properly if no resource available by
        //  calling the function with a reasonable timeout before any calls to
        //  'post'.  Then, both groups of threads will enter a loop to simulate
        //  the steady state.  The 'post' loop will be perturbed to exercise
        //  different portions of code.  The specified timeout will be pretty
        //  important and we will make sure we do not timeout.  At the end
        //  of this first run, we will make a second run with a much lower
        //  timeout which will force *some* waits to timeout.
        //
        // Testing:
        //   void timedWait(bsls::TimeInterval timeout,
        //                  int              *signalInterrupted = 0);
        // --------------------------------------------------------------------

        if (verbose) cout << endl
                          << "Testing 'timedWait'" << endl
                          << "===================" << endl;

        testCase3(bsls::SystemClockType::e_REALTIME);
        testCase3(bsls::SystemClockType::e_MONOTONIC);

      } break;
      case 2: {
        // --------------------------------------------------------------------
        // TESTING 'wait' and 'post'
        //
        // Concerns:
        //   1. wait() blocks the thread when no resource is available,
        //      and then decrements the count
        //   2. post() increments the count
        //
        // Plan:
        //  Create two groups of threads one will call 'post' and the other
        //  will call 'wait'.  To address concern 1, we will use a barrier and
        //  a counter to make sure that waiting threads are blocked into wait
        //  state before any calls to 'post'.  After that, we will try to reach
        //  a steady state by calling the two functions in a loop and perturb
        //  the 'post' operation by adding small delays to exercise different
        //  parts of the code.
        //
        // Testing:
        //   void post();
        //   void wait(int *signalInterrupted = 0);
        // --------------------------------------------------------------------

        if (verbose) cout << endl
                          << "Testing 'wait' and 'post'" << endl
                          << "=========================" << endl;

        bslmt::ThreadUtil::Handle threads[10];
        MyBarrier barrier(6);
        bsls::AtomicInt past(0);
        Obj sem;

        struct ThreadInfo2 info;
        info.d_numIterations = 10000; // number of ops per thread
        info.d_barrier = &barrier;
        info.d_sem = &sem;
        info.d_past = &past;

        for (int i = 0; i < 5; ++i) {
            ASSERT(0 == bslmt::ThreadUtil::create(&threads[i * 2],
                                                 thread2Post,
                                                 &info));

            ASSERT(0 == bslmt::ThreadUtil::create(&threads[i * 2 + 1],
                                                 thread2Wait,
                                                 &info));
        }
        bslmt::ThreadUtil::microSleep(1000 * 100);
        ASSERT(0 == past);
        barrier.wait();
        bslmt::ThreadUtil::microSleep(1000 * 200);
        ASSERT(0 != past);

        for (int i = 0; i < 10; ++i) {
            ASSERT(0 == bslmt::ThreadUtil::join(threads[i]));
        }

      } break;
      case 1: {
        // --------------------------------------------------------------------
        // BREATHING TEST:
        //
        // Exercises basic functionality.
        // --------------------------------------------------------------------

        if (verbose) cout << endl
                          << "Breathing Test" << endl
                          << "==============" << endl;
        {
            Obj X;
            X.post();
            X.post(2);
            X.wait();
            ASSERT(0 == X.timedWait(bsls::SystemTime::nowRealtimeClock() +
                                    bsls::TimeInterval(60)));
            ASSERT(0 == X.tryWait());
            ASSERT(0 != X.tryWait());
            ASSERT(0 != X.timedWait(bsls::SystemTime::nowRealtimeClock() +
                                    bsls::TimeInterval(1)));
        }
      } break;
      default: {
        cerr << "WARNING: CASE `" << test << "' NOT FOUND." << endl;
        testStatus = -1;
      }
    }

    if (testStatus > 0) {
        cerr << "Error, non-zero test status = " << testStatus << "." << endl;
    }
    return testStatus;
}