/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2005 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see . * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * check_list.c - check that gwlib/list.c works */ #include #include #include #include "gwlib/gwlib.h" #define NUM_PRODUCERS (4) #define NUM_CONSUMERS (4) #define NUM_ITEMS_PER_PRODUCER (1*1000) struct producer_info { List *list; long start_index; long id; }; static char received[NUM_PRODUCERS * NUM_ITEMS_PER_PRODUCER]; typedef struct { long producer; long num; long index; } Item; static Item *new_item(long producer, long num, long index) { Item *item; item = gw_malloc(sizeof(Item)); item->producer = producer; item->num = num; item->index = index; return item; } static void producer(void *arg) { long i, index; long id; struct producer_info *info; info = arg; id = gwthread_self(); index = info->start_index; for (i = 0; i < NUM_ITEMS_PER_PRODUCER; ++i, ++index) gwlist_produce(info->list, new_item(id, i, index)); gwlist_remove_producer(info->list); } static void consumer(void *arg) { List *list; Item *item; list = arg; for (;;) { item = gwlist_consume(list); if (item == NULL) break; received[item->index] = 1; gw_free(item); } } static void init_received(void) { memset(received, 0, sizeof(received)); } static void main_for_producer_and_consumer(void) { List *list; int i; Item *item; struct producer_info tab[NUM_PRODUCERS]; long p, n, index; int errors; list = gwlist_create(); init_received(); for (i = 0; i < NUM_PRODUCERS; ++i) { tab[i].list = list; tab[i].start_index = i * NUM_ITEMS_PER_PRODUCER; gwlist_add_producer(list); tab[i].id = gwthread_create(producer, tab + i); } for (i = 0; i < NUM_CONSUMERS; ++i) gwthread_create(consumer, list); gwthread_join_every(producer); gwthread_join_every(consumer); while (gwlist_len(list) > 0) { item = gwlist_get(list, 0); gwlist_delete(list, 0, 1); warning(0, "main: %ld %ld %ld", (long) item->producer, item->num, item->index); } errors = 0; for (p = 0; p < NUM_PRODUCERS; ++p) { for (n = 0; n < NUM_ITEMS_PER_PRODUCER; ++n) { index = p * NUM_ITEMS_PER_PRODUCER + n; if (!received[index]) { error(0, "Not received: producer=%ld " "item=%ld index=%ld", tab[p].id, n, index); errors = 1; } } } if (errors) panic(0, "Not all messages were received."); } static int compare_cstr(void *item, void *pat) { /* Remove a macro definition of strcmp to prevent warnings from * a broken version in the glibc libary. */ #undef strcmp return strcmp(item, pat) == 0; } static void main_for_list_add_and_delete(void) { static char *items[] = { "one", "two", "three", }; int num_items = sizeof(items) / sizeof(items[0]); int num_repeats = 3; int i, j; char *p; List *list; list = gwlist_create(); for (j = 0; j < num_repeats; ++j) for (i = 0; i < num_items; ++i) gwlist_append(list, items[i]); gwlist_delete_matching(list, items[0], compare_cstr); for (i = 0; i < gwlist_len(list); ++i) { p = gwlist_get(list, i); if (strcmp(p, items[0]) == 0) panic(0, "list contains `%s' after deleting it!", items[0]); } for (i = 0; i < num_items; ++i) gwlist_delete_equal(list, items[i]); if (gwlist_len(list) != 0) panic(0, "list is not empty after deleting everything"); gwlist_destroy(list, NULL); } static void main_for_extract(void) { static char *items[] = { "one", "two", "three", }; int num_items = sizeof(items) / sizeof(items[0]); int num_repeats = 3; int i, j; char *p; List *list, *extracted; list = gwlist_create(); for (j = 0; j < num_repeats; ++j) for (i = 0; i < num_items; ++i) gwlist_append(list, items[i]); for (j = 0; j < num_items; ++j) { extracted = gwlist_extract_matching(list, items[j], compare_cstr); if (extracted == NULL) panic(0, "no extracted elements, should have!"); for (i = 0; i < gwlist_len(list); ++i) { p = gwlist_get(list, i); if (strcmp(p, items[j]) == 0) panic(0, "list contains `%s' after " "extracting it!", items[j]); } for (i = 0; i < gwlist_len(extracted); ++i) { p = gwlist_get(extracted, i); if (strcmp(p, items[j]) != 0) panic(0, "extraction returned wrong element!"); } gwlist_destroy(extracted, NULL); } if (gwlist_len(list) != 0) panic(0, "list is not empty after extracting everything"); gwlist_destroy(list, NULL); } int main(void) { gwlib_init(); log_set_output_level(GW_INFO); main_for_list_add_and_delete(); main_for_extract(); main_for_producer_and_consumer(); gwlib_shutdown(); return 0; }