| /* This program is used to test that one-time-construction |
| * works correctly, even in the presence of several threads. |
| */ |
| |
| #include <new> |
| #include <pthread.h> |
| #include <stdio.h> |
| |
| #define MAX_THREADS 100 |
| |
| class Foo { |
| public: |
| Foo() { mValue++; } |
| int getValue() { return mValue; } |
| private: |
| static int mValue; |
| }; |
| |
| int Foo::mValue; |
| |
| static Foo* getInstance(void) |
| { |
| // This construct forces the static creation of _instance |
| // the first time that getInstance() is called, in a thread-safe |
| // way. |
| static Foo _instance; |
| return &_instance; |
| } |
| |
| static Foo* sInstances[MAX_THREADS]; |
| static pthread_t sThreads[MAX_THREADS]; |
| |
| static void* thread_run(void* arg) |
| { |
| int index = reinterpret_cast<int>(arg); |
| sInstances[index] = getInstance(); |
| return NULL; |
| } |
| |
| int main(void) |
| { |
| /* Create all the threads */ |
| for (int nn = 0; nn < MAX_THREADS; nn++) { |
| pthread_create( &sThreads[nn], NULL, thread_run, reinterpret_cast<void*>(nn) ); |
| } |
| /* Wait for their completion */ |
| for (int nn = 0; nn < MAX_THREADS; nn++) { |
| void* dummy; |
| pthread_join( sThreads[nn], &dummy ); |
| } |
| /* Get the instance */ |
| Foo* foo = getInstance(); |
| |
| if (foo == NULL) { |
| fprintf(stderr, "ERROR: Foo instance is NULL!\n"); |
| return 1; |
| } |
| |
| if (foo->getValue() != 1) { |
| fprintf(stderr, "ERROR: Foo constructor called %d times (1 expected)\n", |
| foo->getValue()); |
| return 2; |
| } |
| |
| int count = 0; |
| for (int nn = 0; nn < MAX_THREADS; nn++) { |
| if (sInstances[nn] != foo) |
| count++; |
| } |
| |
| if (count != 0) { |
| fprintf(stderr, "ERROR: There are %d invalid instance pointers!\n", count); |
| return 3; |
| } |
| return 0; |
| } |