Home | History | Annotate | Download | only in tests
      1 /* This program is used to test that one-time-construction
      2  * works correctly, even in the presence of several threads.
      3  */
      4 
      5 #include <new>
      6 #include <pthread.h>
      7 #include <stdio.h>
      8 
      9 #define MAX_THREADS 100
     10 
     11 class Foo {
     12 public:
     13     Foo() { mValue++; }
     14     int getValue() { return mValue; }
     15 private:
     16     static int  mValue;
     17 };
     18 
     19 int Foo::mValue;
     20 
     21 static Foo*  getInstance(void)
     22 {
     23     // This construct forces the static creation of _instance
     24     // the first time that getInstance() is called, in a thread-safe
     25     // way.
     26     static Foo  _instance;
     27     return &_instance;
     28 }
     29 
     30 static Foo*       sInstances[MAX_THREADS];
     31 static pthread_t  sThreads[MAX_THREADS];
     32 
     33 static void* thread_run(void* arg)
     34 {
     35     int index = (int)(intptr_t)arg;
     36     sInstances[index] = getInstance();
     37     return NULL;
     38 }
     39 
     40 int main(void)
     41 {
     42     /* Create all the threads */
     43     for (int nn = 0; nn < MAX_THREADS; nn++) {
     44         pthread_create( &sThreads[nn], NULL, thread_run, reinterpret_cast<void*>(nn) );
     45     }
     46     /* Wait for their completion */
     47     for (int nn = 0; nn < MAX_THREADS; nn++) {
     48         void* dummy;
     49         pthread_join( sThreads[nn], &dummy );
     50     }
     51     /* Get the instance */
     52     Foo*  foo = getInstance();
     53 
     54     if (foo == NULL) {
     55         fprintf(stderr, "ERROR: Foo instance is NULL!\n");
     56         return 1;
     57     }
     58 
     59     if (foo->getValue() != 1) {
     60         fprintf(stderr, "ERROR: Foo constructor called %d times (1 expected)\n",
     61                 foo->getValue());
     62         return 2;
     63     }
     64 
     65     int count = 0;
     66     for (int nn = 0; nn < MAX_THREADS; nn++) {
     67         if (sInstances[nn] != foo)
     68             count++;
     69     }
     70 
     71     if (count != 0) {
     72         fprintf(stderr, "ERROR: There are %d invalid instance pointers!\n", count);
     73         return 3;
     74     }
     75     return 0;
     76 }
     77