Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
check_list.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * check_list.c - check that gwlib/list.c works
59  */
60 
61 #include <string.h>
62 #include <unistd.h>
63 #include <signal.h>
64 
65 #include "gwlib/gwlib.h"
66 
67 #define NUM_PRODUCERS (4)
68 #define NUM_CONSUMERS (4)
69 #define NUM_ITEMS_PER_PRODUCER (1*1000)
70 
71 struct producer_info {
74  long id;
75 };
76 
77 
79 
80 
81 typedef struct {
82  long producer;
83  long num;
84  long index;
85 } Item;
86 
87 
88 static Item *new_item(long producer, long num, long index) {
89  Item *item;
90 
91  item = gw_malloc(sizeof(Item));
92  item->producer = producer;
93  item->num = num;
94  item->index = index;
95  return item;
96 }
97 
98 
99 static void producer(void *arg) {
100  long i, index;
101  long id;
102  struct producer_info *info;
103 
104  info = arg;
105 
106  id = gwthread_self();
107  index = info->start_index;
108  for (i = 0; i < NUM_ITEMS_PER_PRODUCER; ++i, ++index)
109  gwlist_produce(info->list, new_item(id, i, index));
111 }
112 
113 static void consumer(void *arg) {
114  List *list;
115  Item *item;
116 
117  list = arg;
118  for (;;) {
119  item = gwlist_consume(list);
120  if (item == NULL)
121  break;
122  received[item->index] = 1;
123  gw_free(item);
124  }
125 }
126 
127 
128 static void init_received(void) {
129  memset(received, 0, sizeof(received));
130 }
131 
132 
134  List *list;
135  int i;
136  Item *item;
137  struct producer_info tab[NUM_PRODUCERS];
138  long p, n, index;
139  int errors;
140 
141  list = gwlist_create();
142  init_received();
143 
144  for (i = 0; i < NUM_PRODUCERS; ++i) {
145  tab[i].list = list;
146  tab[i].start_index = i * NUM_ITEMS_PER_PRODUCER;
147  gwlist_add_producer(list);
148  tab[i].id = gwthread_create(producer, tab + i);
149  }
150  for (i = 0; i < NUM_CONSUMERS; ++i)
151  gwthread_create(consumer, list);
152 
155 
156  while (gwlist_len(list) > 0) {
157  item = gwlist_get(list, 0);
158  gwlist_delete(list, 0, 1);
159  warning(0, "main: %ld %ld %ld", (long) item->producer,
160  item->num, item->index);
161  }
162 
163  errors = 0;
164  for (p = 0; p < NUM_PRODUCERS; ++p) {
165  for (n = 0; n < NUM_ITEMS_PER_PRODUCER; ++n) {
166  index = p * NUM_ITEMS_PER_PRODUCER + n;
167  if (!received[index]) {
168  error(0, "Not received: producer=%ld "
169  "item=%ld index=%ld",
170  tab[p].id, n, index);
171  errors = 1;
172  }
173  }
174  }
175 
176  if (errors)
177  panic(0, "Not all messages were received.");
178 }
179 
180 
181 static int compare_cstr(void *item, void *pat) {
182  /* Remove a macro definition of strcmp to prevent warnings from
183  * a broken version in the glibc libary. */
184  #undef strcmp
185  return strcmp(item, pat) == 0;
186 }
187 
188 
189 static void main_for_list_add_and_delete(void) {
190  static char *items[] = {
191  "one",
192  "two",
193  "three",
194  };
195  int num_items = sizeof(items) / sizeof(items[0]);
196  int num_repeats = 3;
197  int i, j;
198  char *p;
199  List *list;
200 
201  list = gwlist_create();
202 
203  for (j = 0; j < num_repeats; ++j)
204  for (i = 0; i < num_items; ++i)
205  gwlist_append(list, items[i]);
206  gwlist_delete_matching(list, items[0], compare_cstr);
207  for (i = 0; i < gwlist_len(list); ++i) {
208  p = gwlist_get(list, i);
209  if (strcmp(p, items[0]) == 0)
210  panic(0, "list contains `%s' after deleting it!",
211  items[0]);
212  }
213 
214  for (i = 0; i < num_items; ++i)
215  gwlist_delete_equal(list, items[i]);
216  if (gwlist_len(list) != 0)
217  panic(0, "list is not empty after deleting everything");
218 
219  gwlist_destroy(list, NULL);
220 }
221 
222 
223 static void main_for_extract(void) {
224  static char *items[] = {
225  "one",
226  "two",
227  "three",
228  };
229  int num_items = sizeof(items) / sizeof(items[0]);
230  int num_repeats = 3;
231  int i, j;
232  char *p;
233  List *list, *extracted;
234 
235  list = gwlist_create();
236 
237  for (j = 0; j < num_repeats; ++j)
238  for (i = 0; i < num_items; ++i)
239  gwlist_append(list, items[i]);
240 
241  for (j = 0; j < num_items; ++j) {
242  extracted = gwlist_extract_matching(list, items[j],
243  compare_cstr);
244  if (extracted == NULL)
245  panic(0, "no extracted elements, should have!");
246  for (i = 0; i < gwlist_len(list); ++i) {
247  p = gwlist_get(list, i);
248  if (strcmp(p, items[j]) == 0)
249  panic(0, "list contains `%s' after "
250  "extracting it!",
251  items[j]);
252  }
253  for (i = 0; i < gwlist_len(extracted); ++i) {
254  p = gwlist_get(extracted, i);
255  if (strcmp(p, items[j]) != 0)
256  panic(0,
257  "extraction returned wrong element!");
258  }
259  gwlist_destroy(extracted, NULL);
260  }
261 
262  if (gwlist_len(list) != 0)
263  panic(0, "list is not empty after extracting everything");
264 
265  gwlist_destroy(list, NULL);
266 }
267 
268 
269 int main(void) {
270  gwlib_init();
275  gwlib_shutdown();
276  return 0;
277 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void info(int err, const char *fmt,...)
Definition: log.c:636
long gwthread_self(void)
long producer
Definition: check_list.c:82
void gwlist_append(List *list, void *item)
Definition: list.c:179
void gwlist_produce(List *list, void *item)
Definition: list.c:411
long gwlist_len(List *list)
Definition: list.c:166
static Item * new_item(long producer, long num, long index)
Definition: check_list.c:88
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define NUM_CONSUMERS
Definition: check_list.c:68
#define NUM_PRODUCERS
Definition: check_list.c:67
static void producer(void *arg)
Definition: check_list.c:99
List * gwlist_extract_matching(List *list, void *pat, gwlist_item_matches_t *cmp)
Definition: list.c:322
void gwthread_join_every(gwthread_func_t *func)
static char received[NUM_PRODUCERS *NUM_ITEMS_PER_PRODUCER]
Definition: check_list.c:78
#define NUM_ITEMS_PER_PRODUCER
Definition: check_list.c:69
static void main_for_list_add_and_delete(void)
Definition: check_list.c:189
List * list
Definition: check_list.c:72
long num
Definition: check_list.c:83
long start_index
Definition: check_list.c:73
void log_set_output_level(enum output_level level)
Definition: log.c:217
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
static void main_for_extract(void)
Definition: check_list.c:223
void gwlist_remove_producer(List *list)
Definition: list.c:401
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
void warning(int err, const char *fmt,...)
Definition: log.c:624
#define gwthread_create(func, arg)
Definition: gwthread.h:90
static void init_received(void)
Definition: check_list.c:128
static void consumer(void *arg)
Definition: check_list.c:113
int main(void)
Definition: check_list.c:269
long gwlist_delete_matching(List *list, void *pat, gwlist_item_matches_t *matches)
Definition: list.c:240
void * gwlist_consume(List *list)
Definition: list.c:427
Definition: log.h:69
#define panic
Definition: log.h:87
static int compare_cstr(void *item, void *pat)
Definition: check_list.c:181
void gwlib_shutdown(void)
Definition: gwlib.c:94
#define gwlist_create()
Definition: list.h:136
static void main_for_producer_and_consumer(void)
Definition: check_list.c:133
void gwlib_init(void)
Definition: gwlib.c:78
void gwlist_add_producer(List *list)
Definition: list.c:383
Definition: list.c:102
long index
Definition: check_list.c:84
struct Item Item
Definition: dict.c:74
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.