1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2009 Index Data
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <sys/types.h>
56 #include <idzebra/flock.h>
59 static char seq[1000];
60 static char *seqp = 0;
62 #define NUM_THREADS 100
65 pthread_cond_t sleep_cond = PTHREAD_COND_INITIALIZER;
66 pthread_mutex_t sleep_mutex = PTHREAD_MUTEX_INITIALIZER;
71 static void small_sleep(void)
77 struct timespec abstime;
80 gettimeofday(&now, 0);
81 abstime.tv_sec = now.tv_sec;
82 abstime.tv_nsec = 1000000 + now.tv_usec * 1000;
83 if (abstime.tv_nsec > 1000000000) /* 1s = 1e9 ns */
85 abstime.tv_nsec -= 1000000000;
88 pthread_mutex_lock(&sleep_mutex);
89 pthread_cond_timedwait(&sleep_cond, &sleep_mutex, &abstime);
90 pthread_mutex_unlock(&sleep_mutex);
95 void *run_func(void *arg)
98 int *pdata = (int*) arg;
99 int use_write_lock = *pdata;
100 ZebraLockHandle lh = zebra_lock_create(0, "my.LCK");
101 for (i = 0; i<2; i++)
103 int write_lock = use_write_lock;
105 if (use_write_lock == 2) /* random lock */
106 write_lock = (rand() & 3) == 3 ? 1 : 0;
112 write(test_fd, "L", 1);
116 write(test_fd, "U", 1);
124 write(test_fd, "l", 1);
128 write(test_fd, "u", 1);
133 zebra_lock_destroy(lh);
139 DWORD WINAPI ThreadProc(void *p)
146 static void tst_thread(int num, int write_flag)
149 HANDLE handles[NUM_THREADS];
150 DWORD dwThreadId[NUM_THREADS];
152 #if YAZ_POSIX_THREADS
153 pthread_t child_thread[NUM_THREADS];
155 int i, id[NUM_THREADS];
158 assert (num <= NUM_THREADS);
159 for (i = 0; i < num; i++)
162 #if YAZ_POSIX_THREADS
163 pthread_create(&child_thread[i], 0 /* attr */, run_func, &id[i]);
168 void *pData = &id[i];
169 handles[i] = CreateThread(
170 NULL, /* default security attributes */
171 0, /* use default stack size */
172 ThreadProc, /* thread function */
173 pData, /* argument to thread function */
174 0, /* use default creation flags */
175 &dwThreadId[i]); /* returns the thread identifier */
180 #if YAZ_POSIX_THREADS
181 for (i = 0; i<num; i++)
182 pthread_join(child_thread[i], 0);
185 WaitForMultipleObjects(num, handles, TRUE, INFINITE);
187 for (i = 0; i < num; i++)
188 YAZ_CHECK(id[i] == 123);
190 yaz_log(YLOG_LOG, "tst_thread(%d,%d) returns seq=%s",
191 num, write_flag, seq);
194 static void tst(void)
196 tst_thread(4, 1); /* write locks */
202 YAZ_CHECK_EQ(seq[i], 'L');
203 YAZ_CHECK_EQ(seq[i+1], 'U');
208 tst_thread(6, 0); /* read locks */
210 tst_thread(20, 2); /* random locks */
219 for (i = 0; i<2; i++)
228 for (i = 0; i<2; i++)
231 waitpid(pid[i], &status, 0);
232 YAZ_CHECK(status == 0);
239 int main(int argc, char **argv)
241 YAZ_CHECK_INIT(argc, argv);
244 /* ensure the flock system logs in our test */
245 yaz_log_init_level(yaz_log_mask_str("flock"));
249 test_fd = open("tstflock.out", (O_BINARY|O_CREAT|O_RDWR), 0666);
250 YAZ_CHECK(test_fd != -1);
262 * c-file-style: "Stroustrup"
263 * indent-tabs-mode: nil
265 * vim: shiftwidth=4 tabstop=8 expandtab