1 // shibthreadswin32test.cpp : by Aaron Wohl xshib@awohl.com.
5 CondWait broadcast is not implemented on win32. The semantics are different for
6 broadcast like events on win32. If waking multiple waiters is needed then
7 need to think about it.
9 CondWait lock realease/wake up/lock get are not atomic on win32. I dont think
10 that matters the way its used. On wake up CondWait waits for the condition event or timeout. After wake up it locks the mutex again. Its not guarenteed that the one process that was signaled is the one that gets the lock next.
14 #include "shib-threads.h"
19 using namespace shibboleth;
25 fprintf(stderr,"assert failed " #xxx); \
30 static volatile int basic_loop_count;
31 #define NUM_BASIC_LOOP (100)
33 static do_exit(int rc)
36 cout << "press a key to exit" << endl;
37 cout << "exit code is " << rc << " (0 is good)" << endl;
42 static void *basic_loop_thread(void *x)
44 for(int i=0;i<NUM_BASIC_LOOP;i++)
49 static void test_basic_loop(void)
51 Thread *athr=Thread::create(&basic_loop_thread,0);
54 athr->join(&return_val);
55 ASSERT(basic_loop_count==NUM_BASIC_LOOP);
58 static RWLock *arwlock;
60 static int roll(int n)
65 static int shared_count;
66 #define NUM_READERS (3)
67 static volatile bool in_readern[NUM_READERS];
69 static void check_shared(void)
72 for(int i=0;i<NUM_READERS;i++)
75 ASSERT(share_count>0);
76 ASSERT(share_count<=NUM_READERS);
81 static int num_keys_disposed;
83 static void key_test_fcn(void *x)
88 static void *lock_reader(void *x)
90 int locker_num=int(x);
91 ThreadKey *akey=ThreadKey::create(key_test_fcn);
94 for(int i=0;i<NUM_BASIC_LOOP;i++) {
95 ASSERT(arwlock->rdlock()==0);
96 in_readern[locker_num]=true;
98 // make sure the thread local storage really is thread local
99 // if its not some other reader will trash it
100 ASSERT(akey->getData()==x);
102 in_readern[locker_num]=false;
103 ASSERT(arwlock->unlock()==0);
110 static void *lock_writer(void *y)
112 for(int i=0;i<NUM_BASIC_LOOP;i++) {
113 ASSERT(arwlock->wrlock()==0);
115 ASSERT(arwlock->unlock()==0);
121 static void test_rwlock()
123 arwlock=RWLock::create();
125 bool cant_unlock_an_unlocked_lock=(arwlock->unlock()!=0);
126 ASSERT(cant_unlock_an_unlocked_lock);
129 for(int i=0;i<NUM_READERS;i++) {
130 Thread *athr=Thread::create(&lock_reader,(void *)i);
133 Thread *athw=Thread::create(&lock_writer,0);
138 Thread *some_thread=tl.front();
140 some_thread->join(&return_val);
144 ASSERT(num_keys_disposed==NUM_READERS);
147 static void *empty_thread(void *x)
152 static void test_detach(void)
154 Thread *ath=Thread::create(empty_thread,0);
155 ASSERT(ath->detach()==0);
156 // cant detch or join after already detach
157 ASSERT(ath->detach()!=0);
159 ASSERT(ath->join(&return_val)!=0);
160 ASSERT(ath->detach()!=0);
164 static int in_kill_proc;
166 static void *kill_me(void *x)
175 static void test_kill(void)
177 Thread *ath=Thread::create(kill_me,0);
178 while(in_kill_proc<3)
181 ASSERT(ath->kill(23)==0);
185 static void test_detach_kill(void)
191 static void test_cond_timeout(void)
193 Mutex *m=Mutex::create();
195 CondWait *cw=CondWait::create();
197 ASSERT(m->lock()==0);
198 time_t start_time=time(0L);
199 #define DELAY_TIME (7)
200 ASSERT(cw->timedwait(m,DELAY_TIME)==0);
201 int slept_for=time(0L)-start_time;
202 ASSERT(m->unlock()==0);
205 int delta_time=abs(DELAY_TIME-slept_for);
208 cout << "CondWait: timed test ok" << endl;
212 static int cond_counter;
213 static CondWait *cond_wait;
215 static void *cond_incrementer(void *x)
217 Mutex *cm=(Mutex *)(x);
218 for(int i=0;i<NUM_BASIC_LOOP;i++) {
219 ASSERT(cm->lock()==0);
221 if(cond_counter==(NUM_BASIC_LOOP+NUM_BASIC_LOOP/2))
222 ASSERT(cond_wait->signal()==0);
223 ASSERT(cm->lock()==0);
228 static void test_cond_signal(void)
230 Mutex *cm=Mutex::create();
232 ASSERT(cm->lock()==0);
233 cond_wait=CondWait::create();
235 for(int i=0;i<2;i++) {
236 Thread *athr=Thread::create(&cond_incrementer,(void *)cm);
240 ASSERT(cond_wait->wait(cm)==0);
241 ASSERT(cm->unlock()==0);
243 Thread *some_thread=tl.front();
245 some_thread->join(&return_val);
250 cout << "CondWait: signal test ok" << endl;
253 static void test_cond_wait(void)
259 static void protected_run_tests(void)
267 static void run_tests(void)
270 protected_run_tests();
272 cout << "caught error" << s << endl;
275 cout << "caught unknown error" << endl;
281 int main(int argc, char* argv[])
283 cout << "testing shib-threads, will take like 5min, look for an ok at the end\n";
285 cout << "tests done\n";
286 cout << "readers shared " << shared_count << " times (0 shares is bad)" << endl;