1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2011 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
36 #include <sys/types.h>
59 #include <idzebra/flock.h>
62 static char seq[1000];
63 static char *seqp = 0;
65 #define NUM_THREADS 100
68 pthread_cond_t sleep_cond = PTHREAD_COND_INITIALIZER;
69 pthread_mutex_t sleep_mutex = PTHREAD_MUTEX_INITIALIZER;
74 static void small_sleep(void)
80 struct timespec abstime;
83 gettimeofday(&now, 0);
84 abstime.tv_sec = now.tv_sec;
85 abstime.tv_nsec = 1000000 + now.tv_usec * 1000;
86 if (abstime.tv_nsec > 1000000000) /* 1s = 1e9 ns */
88 abstime.tv_nsec -= 1000000000;
91 pthread_mutex_lock(&sleep_mutex);
92 pthread_cond_timedwait(&sleep_cond, &sleep_mutex, &abstime);
93 pthread_mutex_unlock(&sleep_mutex);
98 void *run_func(void *arg)
101 int *pdata = (int*) arg;
102 int use_write_lock = *pdata;
103 ZebraLockHandle lh = zebra_lock_create(0, "my.LCK");
104 for (i = 0; i<2; i++)
106 int write_lock = use_write_lock;
108 if (use_write_lock == 2) /* random lock */
109 write_lock = (rand() & 3) == 3 ? 1 : 0;
115 write(test_fd, "L", 1);
119 write(test_fd, "U", 1);
127 write(test_fd, "l", 1);
131 write(test_fd, "u", 1);
136 zebra_lock_destroy(lh);
142 DWORD WINAPI ThreadProc(void *p)
149 static void tst_thread(int num, int write_flag)
152 HANDLE handles[NUM_THREADS];
153 DWORD dwThreadId[NUM_THREADS];
155 #if YAZ_POSIX_THREADS
156 pthread_t child_thread[NUM_THREADS];
158 int i, id[NUM_THREADS];
161 assert (num <= NUM_THREADS);
162 for (i = 0; i < num; i++)
165 #if YAZ_POSIX_THREADS
166 pthread_create(&child_thread[i], 0 /* attr */, run_func, &id[i]);
171 void *pData = &id[i];
172 handles[i] = CreateThread(
173 NULL, /* default security attributes */
174 0, /* use default stack size */
175 ThreadProc, /* thread function */
176 pData, /* argument to thread function */
177 0, /* use default creation flags */
178 &dwThreadId[i]); /* returns the thread identifier */
183 #if YAZ_POSIX_THREADS
184 for (i = 0; i<num; i++)
185 pthread_join(child_thread[i], 0);
188 WaitForMultipleObjects(num, handles, TRUE, INFINITE);
190 for (i = 0; i < num; i++)
191 YAZ_CHECK(id[i] == 123);
193 yaz_log(YLOG_LOG, "tst_thread(%d,%d) returns seq=%s",
194 num, write_flag, seq);
197 static void tst(void)
199 tst_thread(4, 1); /* write locks */
205 YAZ_CHECK_EQ(seq[i], 'L');
206 YAZ_CHECK_EQ(seq[i+1], 'U');
211 tst_thread(6, 0); /* read locks */
213 tst_thread(20, 2); /* random locks */
222 for (i = 0; i<2; i++)
231 for (i = 0; i<2; i++)
234 waitpid(pid[i], &status, 0);
235 YAZ_CHECK(status == 0);
242 int main(int argc, char **argv)
244 YAZ_CHECK_INIT(argc, argv);
247 /* ensure the flock system logs in our test */
248 yaz_log_init_level(yaz_log_mask_str("flock"));
252 test_fd = open("tstflock.out", (O_BINARY|O_CREAT|O_RDWR), 0666);
253 YAZ_CHECK(test_fd != -1);
265 * c-file-style: "Stroustrup"
266 * indent-tabs-mode: nil
268 * vim: shiftwidth=4 tabstop=8 expandtab